题意有点迷不造思路很简单但不造怎么求随机数,纠结了一会后直接粘上题目所给的代码稍加修改A了。
const int _K=50268147,_B=6082187,_P=100000007;
int _X;
inline int get_rand(int _l,int _r){
_X=((long long)_K*_X+_B)%_P;
return _X%(_r-_l+1)+_l;
}
int n,m,k,seed,xx,yy;
int x[1000006],y[1000006],vx[N],vy[N];
void Init(){
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
scanf("%d%d%d%d",&n,&m,&k,&seed);
_X=seed;
xx=n,yy=m;
for (int i=1;i<=k;++i)
{
x[i]=get_rand(1,n);
y[i]=get_rand(1,m);
if(!vx[x[i]])
{
vx[x[i]]=1;
xx--;
}
if(!vy[y[i]])
{
vy[y[i]]=1;
yy--;
}
}
printf("%d %d\n",xx,yy);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
Init();
}
return 0;
}
题意:一颗根节点为0的有根树,每个节点上有一定的石子数,每次可以选一个节点上一定数量(不能为0)的石子转移到他的父亲节点上,最后不能移的算输。
思路:设根节点的深度为0,将所有深度为奇数的节点的石子数目xor起来,则先手必胜当且仅当这个xor和不为0。 证明同阶梯博弈。对于偶深度的点上的石子,若对手移动它们,则可模仿操作;对于奇深度上的石子,移动一次即进入偶深度的点。 时空复杂度O(n)。
说实话差一点接近了正确答案了,已经推出来和深度有关,但深搜结果方向错了,围绕nim博弈转化即可。
const int N=1e6+7;
int a[N],f[N],v[N];
int main()
{
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
memset(v,0,sizeof(v));
int ans=0;
for(int i=1; i<=n-1; i++)
{
scanf("%d",&f[i]);
if(!v[f[i]]) v[i]=1;//深度为奇数的节点标记起来;
}
for(int i=0; i<=n-1; i++)
{
scanf("%d",&a[i]);
// printf("%d %d\n",i,v[i]);
if(i&&v[i]) ans^=a[i];
}
if(ans) printf("win\n");
else printf("lose\n");
}
return 0;
}
暂时先pou上这两题,以后再补!这场只A了一题居然涨分了,手残hack unsuccessful一发。。