4.3 Provincial election race simulation game stone tree Game

avatar
avatar

Observe topic each point can only stones to his two sons and the number of stones> = 1.

Obviously this is a ladder NIM. Only parity and the last layer of the same layer will also contribute to prove that it is clear.

So this is in fact almost natural outcome of the game depends on the NIM all contributing to pile stones and XOR.

But I am a little silly not distinguish between SG function and NIM game of contact.

In fact, the number of stones in the game NIM SG function for each contributing heap of stones.

Let's look at this question enumeration moving a pile of stones which can determine whether or not feasible due to the XOR and some violence.

This operation is in fact prove a problem NIM game. Solution is to look after the impact caused by the movement and the final desired outcome to determine the number of stones to move.

Complexity of O (n). Today, most water be the subject of a simulated game but I did not write silly Baji.

//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define pii pair<int,int> 
#define F first
#define S second
#define mk make_pair
#define mod 998244353
#define RE register
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define ull unsigned long long
#define P 1000000000000000ll
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    RE int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int N=17;
int T,n,maxx,ans,sum1;
int a[1<<N],pos[N],sum[1<<N];
int main()
{
	freopen("1.in","r",stdin);
	get(T);
	while(T--)
	{
		get(n);ans=0;sum1=0;
		maxx=(1<<n)-1;
		pos[n]=1;
		fep(n-1,1,i)pos[i]=pos[i+1]^1;
		rep(1,maxx,i)
		{
			sum[i]=sum[i>>1]+1;
			get(a[i]);
			if(pos[sum[i]])ans=ans^a[i];
		}
		if(!ans){puts("0");continue;}
		rep(1,maxx,i)
		{
			if(pos[sum[i]])//将res棋子给两个儿子 使得ans^a[i]^now=0  res=a[i]-now;
			{
				int now=ans^a[i];
				if(a[i]<now)continue;
				sum1=sum1+(sum[i]!=n)+1;
			}
			else//将res个棋子给两个儿子 使得a[i<<1]^ans^(a[i<<1]+res)=0
				//或a[i<<1|1]^ans^(a[i<<1|1]+res)=0; res<=a[i]
			{
				//ans=a[i<<1]+res;
				int res=(ans^a[i<<1])-a[i<<1];
				if(res>=1&&res<=a[i])++sum1;
				res=(ans^a[i<<1|1])-a[i<<1|1];
				if(res>=1&&res<=a[i])++sum1;
			}
		}
		put(sum1);
	}
}

Guess you like

Origin www.cnblogs.com/chdy/p/12628327.html