标签:cnt Industrial CF15C int 题解 sum cf else 周期
分析
对于 \(nim\) 游戏的话,可以去看P2197进行博弈论相关知识的学习。
在得到结论之后,我们就是要求,所有车辆石头的异或和,是否为零,是则后手赢,反之先手赢。
我们考虑每一位来单独处理,计算这些车石头数在每一位有多少个 \(1\),对于第 \(i\) 位而言,若以函数的角度理解,它的周期是 \(2^{i+1}\),每一周期里,有 \(2^i\) 个数字该位为 \(1\)。
因此对于每一位,我们就可以先找出 \(x\) 当前所处的连续 \(1\) 或连续 \(0\) 的片段最远延伸到了多少,然后再找出多少个满周期,最后再加上剩余的数里有多少个该位为 \(1\)。
具体的实现可以详见代码。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int cnt[60];
int cf[60];
int mx=57;
int n,x,mm;
signed main()
{
cf[0]=1;
for(int i=1;i<=mx;i++)cf[i]=cf[i-1]*2;
cin>>n;
for(int i=1;i<=n;i++){
cin>>x>>mm;
for(int j=0;j<=mx;j++){
int m=mm;//这个东西导致我错了很久
int sum=x/cf[j]+1;//找出当前连续段的末端位置
//每一连续段大小都是2^j,所以直接除后加一,乘上2^j减1就是所求
if(x&cf[j]){//x是从1开始,后面取完周期就是从0开始
sum=sum*cf[j]-1;
if(sum-x+1>m)cnt[j]+=m;//特判
else {
cnt[j]+=sum-x+1;
m-=sum-x+1;
sum=m/(cf[j]*2);//周期数
m-=cf[j]*2*sum;
cnt[j]+=sum*cf[j];//一半0,一半1
m-=cf[j];//先有2^j个0
if(m>0)cnt[j]+=m;
}
}
else {
sum=sum*cf[j]-1;
if((sum-x+1)>m)cnt[j]+=0;
else {
m-=sum-x+1;
sum=m/(cf[j]*2);
m-=cf[j]*2*sum;
cnt[j]+=sum*cf[j];//前面同理
if(m>0)cnt[j]+=min(m,cf[j]);//前面就是1了
}
}
cnt[j]%=2;//因为是异或,直接模2即可
}
}
for(int i=0;i<=mx;i++){
if(cnt[i]){//异或和不为0,先手必胜
puts("tolik");
return 0;
}
}
puts("bolik");
return 0;
}
标签:cnt,Industrial,CF15C,int,题解,sum,cf,else,周期 来源: https://www.cnblogs.com/zxhmh/p/15249742.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。