这场数学场
A
要求连续三个数互质 我们可以发现相邻的数一定互质,所以只需满足相隔的数互质即可。
# include <bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a, int b) // 欧几里得算法
{
return b ? gcd(b, a % b) : a;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
int l,r;
cin>>l>>r;
int ans=0;
for(int i=l;i<=r-2;i++)
{
if(gcd(i,i+2)==1)
{
ans++;
i+=2;
}
}
cout<<ans<<endl;
}
return 0;
}
B
模拟以后发现最大的数操作后仍为最大数,可能会出现相同的但不会超过原始最大值
# include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N];
int n,m;
signed main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>m;
int mx=0;
for(int i=1;i<=n;i++)
cin>>a[i],mx=max(mx,a[i]);
while(m--)
{
char x;
int l,r;
cin>>x>>l>>r;
if(x=='-')
{
if(mx>=l&&mx<=r)
mx=mx-1;
}
else if(x=='+')
{
if(mx>=l&&mx<=r)
mx=mx+1;
}
cout<<mx<<" ";
}
cout<<endl;
}
}
C
考察数论
根据裴蜀定理:给定x,y存在ax + by = gcd(x, y)
所以对于一个数我们可以将其变成a[i]+k*gcd(x,y);
那么我们可以实现对每个元素任意次 gcd(a, b) 加减操作
那么我们一定可以将原数组的元素都调整到 [0, gcd(a, b))内,考虑将每个数取模gcd(x,y),枚举每个数a[i]作为最大值的情况,每次的值为a[i-1]+gcd(x,y)-a[i];
# include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int c[N],n,a,b;
int gcd(int a, int b) // 欧几里得算法
{
return b ? gcd(b, a % b) : a;
}
signed main()
{
int T;
cin>>T;
while(T--)
{
cin>>n>>a>>b;
int x=gcd(a,b);
for(int i=1;i<=n;i++)
{
cin>>c[i],c[i]%=x;
}
sort(c+1,c+n+1);
int res=c[n]-c[1];
for(int i=1;i<=n;i++)
{
res=min(res,c[i-1]+x-c[i]);
}
cout<<res<<endl;
}
}
D
我们可以发现一个规律当首尾字母相同时贡献为零,一条从根到叶子的路径是否有得分,只取决于根节点与叶子节点是否相同。相同则无贡献,不同则有贡献。只用看根节点和叶子的情况,先手抢占有利的一方即可。
只有一种特殊情况下需要考虑到路径节点上的’?‘,即当根节点为‘?’,且叶子节点中‘0’、‘1’的数量相等时(也可以都为0),此时双方处于平衡状态,在根节点和叶子节点上先手的一方反而会成为后手,所以Iris需要利用中间路径上的‘?’来拉扯一下,如果中间路径上的’?’数量为奇数,那么通过拉扯就可以使先后手转换,那么Iris就不会亏掉这一分。
# include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
vector<int>e[N];
int n;
string s;
signed main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n-1;i++)
{
int a,b;
cin>>a>>b;
e[a].push_back(b);
e[b].push_back(a);
}
cin>>s;
s=" "+s;
int cnt=0;
int s0=0,s1=0,sw=0;
for(int i=2;i<=n;i++)
{
if(s[i]=='?')
cnt++;
if(e[i].size()==1)
{
if(s[i]=='0')
s0++;
else if(s[i]=='1')
s1++;
else if(s[i]=='?')
sw++;
}
}
int ans=0;
if(s[1]=='0')
{
ans=s1+sw/2+(sw%2==1);
}
else if(s[1]=='1')
{
ans=s0+sw/2+(sw%2==1);
}
else if(s[1]=='?')
{
if(s0==s1)
{
if((cnt-sw)%2==1)
ans=max(s0+sw/2+(sw%2==1),s1+sw/2+(sw%2==1));
else ans=max(ans=s0+sw/2,s1+sw/2);
}
else
ans=max(s0+sw/2,s1+sw/2);
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)
e[i].clear();
}
}