首页 > 技术文章 > AGC035 A - XOR Circle【分析】

lyttt 2019-10-22 09:25 原文

题目传送门

题意简述:

 

 

 (就是连环的意思)

唔,这道题考场上写了个什么神仙做法,数据太水了居然过了:

//
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
#define MAXN 10005
#define LL long long
#define INF 0x3f3f3f3f 
int n,a,ans;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a);
        ans^=a;
    }
    if(ans==0) printf("Yes\n");
    else printf("No\n");
    return 0;
} 

反例还是很容易构造的吧,比如$n$不能被$3$整除的情况(看了下面的分析就可以轻而易举地举出好多反例来了)

 

分析:

1.左右两个数的异或值等于中间的数,那么任意相邻三个数的异或和一定为$0$

2.考虑一般情况,设序列的前$3$个数为$xyz$,且$x^y^z==0$,那么如果要满足任意三个相邻的数的异或和都为0,则下一个数只能为$x$,因为要满足$y^z^这个数==0$,依次推下去,可以发现$n%3==0$时,比如$xyzxyz$在连成环的情况下可以符合要求,反之不能,比如$xyzxy$。也就是这三个数的个数一定要是相等,且均为$n/3$

2.考虑特殊情况,上一种情况中的$xyz$中有2个数相等的时候,剩下那一个数只能为$0$,也就是$0$的个数为$n/3$,另一个数的个数为$n/3*2$。

3.最最特殊的情况,就是全部都是$0$的情况,这种情况不需要判断$n%3==0$。

 

但是,

做这道题的时候该犯的错误,不该犯的错误都犯到位了。

1.没有开ll

2.多组数据不清零(线下考试的时候由于AT数据过于水,重造了数据,没有绑点,但是多组数据)

3.在找不一样的数的时候,用的下面的式子判断,但是,要记得赋$a[0]=-1或INF$,否则在第一个数是0的时候会炸掉。

 1 //不开ll见祖宗 
 2 #include<iostream>
 3 #include<string>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<map>
 7 #include<algorithm>
 8 using namespace std;
 9 #define N 100005
10 #define ll long long
11 #define MOD 1000000007
12 #define INF 0x3f3f3f3f
13 int n;
14 ll a[N],num[10];
15 int cnt[10],tot;
16 int main()
17 {
18     //freopen("circle.in","r",stdin);
19     //freopen("circle.out","w",stdout);
20     int T;scanf("%d",&T);
21     while(T--)
22     {
23         //f**k多组数据不清零
24         tot=0;
25         cnt[1]=cnt[2]=cnt[3]=0;
26         num[1]=num[2]=num[3]=0; 
27         bool f=0;
28         scanf("%d",&n);
29         for(int i=1;i<=n;i++)
30         {
31             scanf("%lld",&a[i]);
32             if(a[i]!=0) f=1;
33         }
34         if(f==0)
35         {//全部都是0 
36             puts("Yes");
37             continue;
38         }
39         sort(a+1,a+n+1);
40         a[0]=INF;
41         for(int i=1;i<=n;i++)
42         {
43             if(a[i]!=a[i-1])
44                 cnt[++tot]++,num[tot]=a[i];
45             else cnt[tot]++;
46             if(tot>3)
47             {
48                 puts("No");
49                 f=0;//混用变量
50                 break; 
51             }
52         } 
53         if(f==0) continue;
54         if(n%3==0)
55         {
56             if(tot==3&&(num[1]^num[2]^num[3])==0&&cnt[1]==n/3&&cnt[2]==n/3&&cnt[3]==n/3)
57             {
58                 puts("Yes");
59                 continue;
60             }
61             if(tot==2&&num[1]==0&&cnt[1]==n/3&&cnt[2]==n/3*2)
62             {
63                 puts("Yes");
64                 continue;
65             }
66         }
67         puts("No");
68     }
69     return 0;
70 }
Code

 

推荐阅读