Bike老爷问了好几天到底要怎样简单的题目你们才能AK啊终于在他每天降难度直到要走了才出了一套我们能AK的题。虽然前几天的题换成llj肯定随便AK。
其实最近有点方虽然通常最后都写完了把该拿的分拿了该拍的拍了,但是并不是很顺利的那种前30min切了T1,再1h切t2拍了最后写t3然后拍这样,这套题推了半天t1没推出来就弃了去搞t2,结果半天把fwt打挂了又去搞t3,开考1h多终于把t3搞出来了才又去回想我的fwt,最后1h先猜了个t1的结论然后先想打个树dp之类的验证发现不会,又证了半天才勉强觉得是对的。t3还没有拍,交题的时候都很虚。如果是正式的考场,特别是像noip比较简单的,这种情况我可能心态就崩了,别说AK,一不小心爆个0也不是不可能。但总得来说先通读题每道有个大概的想法和及时弃题不要对着一个狂肝其他该要的分都不要(去年能要是明白这个道理我大概就不在这里了吧)应该是没错的,然后心态要稳这样?
B 君的第一题hohhot
结论题。画一条链,发现胜负只跟最上面一条边有关,画一朵菊花,发现答案就是和根相连的所有边的异或和。大胆地猜测,这是个结论。考虑和根相连只有一条边的情况,任何一次操作都会改变这条边,那么胜负只跟这条边原本的状态有关。如果根有多条边相连,那么每条边底下的操作情况互不影响,答案就是每条边的答案的异或和。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=100007;
7 typedef long long LL;
8 typedef double db;
9 using namespace std;
10 int n,a[N];
11
12 template<typename T> void read(T &x) {
13 char ch=getchar(); x=0; T f=1;
14 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
15 if(ch=='-') f=-1,ch=getchar();
16 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
17 }
18
19 #define ANS
20 int main() {
21 #ifdef ANS
22 freopen("hohhot.in","r",stdin);
23 freopen("hohhot.out","w",stdout);
24 #endif
25 read(n);
26 For(i,2,n) {
27 int x,y,z;
28 read(x); read(y); read(z);
29 a[x]^=z; a[y]^=z;
30 }
31 For(i,1,n) printf("%d
",a[i]);
32 Formylove;
33 }
B 君的第二题lhasa
这不是一道FWT的裸题么,毕老爷给的标答也就是换一种方式的各种集合变换,和FWT也差不到哪去吧,我觉得noip不会考。。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=1048599;
7 typedef long long LL;
8 typedef double db;
9 using namespace std;
10 int n,k,a[N];
11
12 template<typename T> void read(T &x) {
13 char ch=getchar(); x=0; T f=1;
14 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
15 if(ch=='-') f=-1,ch=getchar();
16 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
17 }
18
19 LL f[N],b[N];
20 void FWT(int n,int F) {
21 for(int i=1;i<n;i<<=1)
22 for(int j=0,pp=(i<<1);j<n;j+=(pp))
23 for(int k=0;k<i;k++) {
24 LL x=f[j+k],y=f[j+k+i];
25 if(F==1) f[j+k+i]=x+y;
26 else f[j+k+i]=y-x;
27 }
28
29 }
30
31 #define ANS
32 int main() {
33 #ifdef ANS
34 freopen("lhasa.in","r",stdin);
35 freopen("lhasa.out","w",stdout);
36 #endif
37 read(n); read(k);
38 For(i,1,n) {
39 read(a[i]);
40 f[a[i]]++;
41 }
42 int up=(1<<k);
43 For(i,0,up) b[i]=f[i];
44 FWT(up,1);
45 For(i,0,up) f[i]=f[i]*f[i];
46 FWT(up,-1);
47 For(i,0,up) f[i]=(f[i]-b[i])/2;
48 //For(i,0,up-1) printf("%lld ",f[i]); puts("");
49 For(i,0,k-1) {
50 Rep(s,up-1,0) if(!(s&(1<<i)))
51 f[s]+=f[s|(1<<i)];
52 }
53 For(s,0,up-1) printf("%lld
",f[s]);
54 Formylove;
55 }
B 君的第三题urumqi
并查集+set启发式合并,之前讲过的一道题。
我开了两个并查集,一个并查集维护和我相同集合的元素,一个并查集维护每个集合不能有的元素。每个集合的每个并查集开个set。
合并的时候启发式合并,不等关秀就在每个集合不能有的元素的set里放进一个对面集合的代表元。相等关系我处理的比较暴力,不管怎么样先合并(启发式)再说,合并到一半发现冲突就把这部分合并都撤销了输出NO否则最终合并完输出YES,因为有撤销操作所以大概要用multiset。
1 //Achen
2 #include<bits/stdc++.h>
3 #define For(i,a,b) for(int i=(a);i<=(b);i++)
4 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
5 #define Formylove return 0
6 const int N=200007;
7 typedef long long LL;
8 typedef double db;
9 using namespace std;
10 int n,sz,x[N],y[N],o[N],ls[N];
11 int sta[N],top,sta2[N],top2;
12 int fa[2][N];
13 multiset<int>s1[N],s2[N];
14
15 template<typename T> void read(T &x) {
16 char ch=getchar(); x=0; T f=1;
17 while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
18 if(ch=='-') f=-1,ch=getchar();
19 for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
20 }
21
22 int find(int x,int f) { return x==fa[f][x]?x:fa[f][x]=find(fa[f][x],f); }
23
24 #define ANS
25 int main() {
26 #ifdef ANS
27 freopen("urumqi.in","r",stdin);
28 freopen("urumqi.out","w",stdout);
29 #endif
30 read(n);
31 For(i,1,n) {
32 read(x[i]); read(y[i]); read(o[i]);
33 ls[++ls[0]]=x[i];
34 ls[++ls[0]]=y[i];
35 }
36 sort(ls+1,ls+ls[0]+1);
37 sz=unique(ls+1,ls+ls[0]+1)-(ls+1);
38 For(i,1,n) {
39 x[i]=lower_bound(ls+1,ls+sz+1,x[i])-ls;
40 y[i]=lower_bound(ls+1,ls+sz+1,y[i])-ls;
41 }
42 For(i,1,sz) {
43 fa[0][i]=i;
44 fa[1][i]=i;
45 s1[i].insert(i);
46 }
47 For(i,1,n) {
48 int u1=find(x[i],1),v1=find(x[i],0);
49 int u2=find(y[i],1),v2=find(y[i],0);
50 if(o[i]) {
51 if(u1==u2) puts("Yes");
52 else {
53 int fl=0;
54 if(s1[u1].size()<s1[u2].size()) swap(u1,u2),swap(v1,v2);
55 fa[1][u2]=u1;
56 top=0;
57 while(s1[u2].size()) {
58 int tp=*s1[u2].begin();
59 if(s2[v1].find(tp)!=s2[v1].end()) {
60 while(top) {
61 int t=sta[top--];
62 s1[u2].insert(t);
63 s1[u1].erase(t);
64 }
65 fl=1;
66 break;
67 }
68 s1[u2].erase(s1[u2].begin());
69 sta[++top]=tp;
70 s1[u1].insert(tp);
71 }
72 if(!fl) {
73 int tpfl=0;
74 if(s2[v1].size()<s2[v2].size()) { tpfl=1; swap(u1,u2),swap(v1,v2); }
75 fa[0][v2]=v1;
76 top2=0;
77 while(s2[v2].size()) {
78 int tp=*s2[v2].begin();
79 if(s1[u1].find(tp)!=s1[u1].end()) {
80 while(top) {
81 int t=sta[top--];
82 if(!tpfl) {
83 s1[u2].insert(t);
84 s1[u1].erase(t);
85 }
86 else {
87 s1[u1].insert(t);
88 s1[u2].erase(t);
89 }
90 }
91 while(top2) {
92 int t=sta2[top2--];
93 s2[v2].insert(t);
94 s2[v1].erase(s2[v1].find(t));
95 }
96 }
97 s2[v2].erase(s2[v2].begin());
98 sta2[++top2]=tp;
99 s2[v1].insert(tp);
100 }
101 }
102 if(fl) {
103 puts("No");
104 fa[1][u1]=u1; fa[1][u2]=u2;
105 fa[0][v1]=v1; fa[0][v2]=v2;
106 }
107 else puts("Yes");
108 }
109 }
110 else {
111 if(u1==u2) puts("No");
112 else {
113 puts("Yes");
114 s2[v1].insert(u2);
115 s2[v2].insert(u1);
116 }
117 }
118 }
119 Formylove;
120 }