CF1780
A.Hayato and School
题目大意:
共\(t\)组数据,每组数据给出一个长度为\(n\)的序列\(a_{i}\),要求找出\(a\)中的三个数,使得它们的和是奇数。若能找到,输出YES
并输出它们在序列\(a\)中的位置,若无解则输出NO
。\((1\leqslant t\leqslant 10^{4},3\leqslant n\leqslant 300,\Sigma n\leqslant 10^{5},1\leqslant a_{i}\leqslant 10^{5})\)
解题思路:
众所周知,若两个数的和是奇数,那么它们一定一个是偶数,一个是奇数;再进一步,若三个数的和是奇数,那么它们不是偶偶奇,就是奇奇奇。于是统计一下序列\(a\)中奇偶数的个数,若出现以上两种情况,输出即可。
贴
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=310;
int T;
int n,a[N];
int ans0[N],ans1[N];
int cnt0,cnt1;
signed main()
{
scanf("%lld",&T);
while (T--)
{
cnt0=cnt1=0;
scanf("%lld",&n);
for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
bool flag=false;
for (int i=1;i<=n;i++)
{
if (a[i]%2==0) ans0[++cnt0]=i;
else ans1[++cnt1]=i;
if (cnt1>=1&&cnt0>=2)
{
printf("YES\n%lld %lld %lld\n",ans0[1],ans0[2],ans1[1]);
flag=true; break;
}
if (cnt1>=3)
{
printf("YES\n%lld %lld %lld\n",ans1[1],ans1[2],ans1[3]);
flag=true; break;
}
}
if (!flag) printf("NO\n");
}
return 0;
}
Ehhh Ah
B.GCD Partition
题目大意:
共 \(t\) 组数据,每组数据给出长度为 \(n\) 的序列 \(a\) ,要求将序列\(a\)分为若干个子段,使得所有子段和的最大公约数最大,输出最大值。\((1\leqslant t\leqslant 10^{4},\Sigma n\leqslant 2\times 10^{5},1\leqslant a_{i}\leqslant 10^{9})\)
解题思路:
有一个结论:\(gcd(a,b,c)\leqslant gcd(a+b,c)\),这里就不证明了,其实很好证。
然后就会发现,我们只需要把序列分成两段,就一定能找到答案。
所以用一个前缀和数组+枚举断点就行。
贴
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int T;
int n,a[N];
int sum[N];
int ans=1;
int gcd(int x,int y)
{
if (!y) return x;
return gcd(y,x%y);;
}
signed main()
{
scanf("%lld",&T);
while (T--)
{
ans=1;
scanf("%lld",&n);
for (int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for (int i=1;i<n;i++) ans=max(ans,gcd(sum[i],sum[n]-sum[i]));
printf("%lld\n",ans);
}
return 0;
}
Ehhh Ah
D. Bit Guessing Game
题目大意:
史交互
共\(t\)组测试用例。
每组测试会有一个数\(n\),刚开始会给出二进制下的 \(n_{2}\) 数位上\(1\)的个数\(cnt\)。每次你有两种操作:
- x
修改操作,每次该操作会使得\(n=n-x\),并给出修改后的\(cnt\)。注意,不能使\(x>n\)! x
此时你输出的\(x\)应满足\(x=n\)
每次修改操作最多出现30次。\((1\leqslant t\leqslant 500,1\leqslant n\leqslant 10^{9})\)
解题思路:
我讨厌交互题一辈子
考虑在二进制下从低位向高位减。若减去后,\(cnt\)有减少,说明那一位上是\(1\),否则是\(0\)。
若某一位原本是\(0\)、因为\(-1\)导致变成了\(1\),那么为了避免这一位产生的影响,在下一次修改时应该把这多出来的\(1\)减掉。
注意特判最高位。若最高位-1后只剩下一个1,应直接加上答案然后跳出去,不然会出现负数。
我宣布这就是史
#incIude <bits/stdc++.h>
#define int long long
using namespace std;
int T;
int pre,cnt,l,l2;
int ans;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>T;
while (T--)
{
ans=l=l2=0;
cin>>pre;
for (int i=0;i<=30&⪯i++)
{
cout<<"- "<<(1<<i)+l<<"\n";
cout.flush();
cin>>cnt;
ans+=(1<<i)+l;
if (cnt==pre-1-l2) l=l2=0;
else
{
if (cnt==1) { ans+=(1<<i); break; }
else l=1<<i,l2=1;
}
pre=cnt;
}
cout<<"! "<<ans<<"\n";
cout.flush();
}
return 0;
}
Ehhh Ah
E.Josuke and Complete Graph
题目大意:
共\(t\)组数据,每组数据给出\(l,r\),表示有一张顶点编号为 \([l,r]\) 的无向带权完全图\(G\),每两个顶点\(u,v\)之间的边的权重为\(gcd(u,v)\),要求给出\(G\)中有多少种不同的边权。\((1\leqslant t\leqslant 100,1\leqslant l\leqslant r\leqslant 10^{18},l\leqslant 10^{9})\)
解题思路:
前置知识:整除分块,我不会。
转化题意,这题就是求\([l,r]\)间所有数对的\(gcd\)的种类数。而对于一个\(gcd\)的值\(g\),若它合法,那么一定满足区间内至少有两个\(g\)的倍数,也就是$$\lfloor\frac{l-1}{g}\rfloor+2\leqslant \lfloor\frac{r}{g}\rfloor$$
可以整除分块做。
同时,需要特判\(l\leqslant g\leqslant r\)的情况,此时答案贡献区间就是\([l,\lfloor\frac{r}{2}\rfloor]\)
不做评价
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T;
int l,r;
int ans;
signed main()
{
scanf("%lld",&T);
while (T--)
{
scanf("%lld%lld",&l,&r);
l--,ans=max(1ll*0,r/2-l);
for (int i=1,j=0;i<=l;i=j+1)
{
j=l/(l/i);
int k=min(j,r/(l/i+2));
if (k>=i) ans+=k-i+1;
}
printf("%lld\n",ans);
}
return 0;
}
Ehhh Ah
F.Three Chairs
题目大意:
给出一个数组\(a\),其中元素各不相同。求满足以下条件的三元组\((a_{k1},a_{k2},a_{k3})\)个数:$$gcd(max(a_{k1},a_{k2},a_{k3}),min(a_{k1},a_{k2},a_{k3})=1)$$\((3\leqslant n\leqslant 3\times 10^{5},1\leqslant a_{i}\leqslant 3\times10^{5})\)
解题思路:
前置知识:莫比乌斯反演,我不会。
\(30min\)过去了,我还不会。
感觉今天不会会了,贴个莫比乌斯反演学习链接,以后找时间继续学。
贴个其他大佬的题解