[AGC043B]123 Triangle
123 Triangle
题解
最开始的序列是含有 
     
      
       
       
         1 
        
       
         , 
        
       
         2 
        
       
         , 
        
       
         3 
        
       
      
        1,2,3 
       
      
    1,2,3的,但当我们进行一次操作后,原序列就会变成只含 
     
      
       
       
         0 
        
       
         , 
        
       
         1 
        
       
         , 
        
       
         2 
        
       
      
        0,1,2 
       
      
    0,1,2的序列,因为 
     
      
       
       
         3 
        
       
      
        3 
       
      
    3一定会被消掉。
 如果 
     
      
       
       
         3 
        
       
      
        3 
       
      
    3与 
     
      
       
       
         3 
        
       
      
        3 
       
      
    3进行相减,那么一定会得到 
     
      
       
       
         0 
        
       
      
        0 
       
      
    0,如果与 
     
      
       
       
         1 
        
       
         / 
        
       
         2 
        
       
      
        1/2 
       
      
    1/2相减,那么就会得到 
     
      
       
       
         2 
        
       
         / 
        
       
         1 
        
       
      
        2/1 
       
      
    2/1,无论如何 
     
      
       
       
         3 
        
       
      
        3 
       
      
    3都会被消掉。
 当消掉 
     
      
       
       
         3 
        
       
      
        3 
       
      
    3之后,我们就只剩 
     
      
       
       
         0 
        
       
         , 
        
       
         1 
        
       
         , 
        
       
         2 
        
       
      
        0,1,2 
       
      
    0,1,2了,考虑答案会是什么。
 对于一个位置上的 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1,如果它的位置的旁边存在 
     
      
       
       
         0 
        
       
         / 
        
       
         2 
        
       
      
        0/2 
       
      
    0/2的时候,它一定可以传递下去,即 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1的数量不会减少。而当它旁边都是 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1的时候,它才会被消掉。
 所以我们要消掉 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1,需要让最后时刻 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1覆盖全场。
 所以存在 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1的时候,要么消掉 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1,此时 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2就不存在了,要么让 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1成为答案,答案自然不可能是 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2了。
 而当 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1不存在时, 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2的二进制位与 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1是等价的,我们可以将 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2当作 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1来考虑。当然,此时的答案是 
     
      
       
       
         0 
        
       
         / 
        
       
         2 
        
       
      
        0/2 
       
      
    0/2。
由于答案只会是 
     
      
       
       
         0 
        
       
         / 
        
       
         1 
        
       
      
        0/1 
       
      
    0/1,所以我们的操作可以看作是模 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2意义下的减法,自然也等价与模 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2意义下的加法。
 既然是加法了,那么就是相邻两位相加得到下一个序列中的数,这不是杨辉三角吗???
 很明显,对于一个长度为 
     
      
       
       
         n 
        
       
      
        n 
       
      
    n的序列,第 
     
      
       
       
         i 
        
       
      
        i 
       
      
    i位贡献位 
     
      
       
       
         ( 
        
        
         
         
           n 
          
         
           − 
          
         
           1 
          
         
         
         
           i 
          
         
           − 
          
         
           1 
          
         
        
       
         ) 
        
       
      
        \binom{n-1}{i-1} 
       
      
    (i−1n−1),我们只要将为 
     
      
       
       
         1 
        
       
      
        1 
       
      
    1的位置的贡献加起来看看奇偶性即可。
但很明显,我们不可能直接通过其阶乘来求解,因为这涉及到其 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2的幂,不能代模。
 但我们可以处理出来它的阶乘含 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2的数量,通过 
     
      
       
       
         2 
        
       
      
        2 
       
      
    2的次数加减判断最后答案的奇偶性。
 时间复杂度 
     
      
       
       
         O 
        
        
        
          ( 
         
        
          n 
         
        
          l 
         
        
          o 
         
        
          g 
          
        
          n 
         
        
          ) 
         
        
       
      
        O\left(nlog\,n\right) 
       
      
    O(nlogn)。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
typedef long long LL;
typedef unsigned long long uLL;
const int mo=1e8+7;
const int jzm=2333;
const int lim=1000000;
const int orG=3,invG=332748118;
const double Pi=acos(-1.0);
const double eps=1e-9;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
template<typename _T>
void read(_T &x){
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+(s^48);s=getchar();}
	x*=f;
}
template<typename _T>
void print(_T x){if(x<0){x=(~x)+1;putchar('-');}if(x>9)print(x/10);putchar(x%10+'0');}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int add(int x,int y,int p){return x+y<p?x+y:x+y-p;}
int qkpow(int a,int s,int p){int t=1;while(s){if(s&1)t=1ll*a*t%p;a=1ll*a*a%p;s>>=1;}return t;}
int n,a[MAXN],ans,cnt[MAXN];
void init(){
	cnt[0]=0;
	for(int i=2;i<=1e6;i<<=1)
		for(int j=i;j<=1e6;j+=i)cnt[j]++;
	//for(int i=1;i<=100;i++)printf("%d:%d\n",i,cnt[i]);
	for(int i=2;i<=1e6;i++)cnt[i]+=cnt[i-1];
}
int C(int x,int y){
	if(x<0||y<0||x<y)return 0;
	return cnt[x]==cnt[y]+cnt[x-y]; 
}
signed main(){
	read(n);for(int i=1;i<=n;i++)scanf("%1d",&a[i]);
	if(n==1){printf("%d\n",a[1]);return 0;}int ft=2;
	for(int i=1;i<n;i++)a[i]=Fabs(a[i]-a[i+1]);n--;
	for(int i=1;i<=n;i++)if(a[i]==1)ft=1;init();
	if(ft==2)for(int i=1;i<=n;i++)a[i]/=2;
	else for(int i=1;i<=n;i++)a[i]&=1;
	for(int i=1;i<=n;i++)ans^=(C(n-1,i-1)&a[i]);
	printf("%d\n",ans*ft);
	return 0;
}
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号