生活随笔
收集整理的這篇文章主要介紹了
# CF1572B Xor of 3(构造)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
解析
你CF還是你CF
省選刷到2017再往前不是很想做了,就來CF玩一玩。
再次感受到被CF淺顏色構造虐的快感。
本題靠著各種亂搞特判在WA了無數次之后艸過去了。
根本沒有什么正確性的玄學做法,但是看CF數據似乎把 nnn 較小的所有情況全都pia到數據里了,小數據全都能正確,這題大數據也沒有什么hack的優(yōu)勢,那它可能真的是對的…
還是來看看優(yōu)美簡潔的正解吧。
不難發(fā)現操作前后異或和不變,因此如果整體異或和為1必然無解。
考慮奇數怎么做。
分別對 (n?2,n),(n?4,n?2),(n?6,n?4)...(1,3)(n-2,n),(n-4,n-2),(n-6,n-4)...(1,3)(n?2,n),(n?4,n?2),(n?6,n?4)...(1,3) 操作一次,這樣序列就變成了 0aabbcc...0aabbcc...0aabbcc... 的樣子。
然后再對 (1,3)(3,5)...(n?2,n)(1,3)(3,5)...(n-2,n)(1,3)(3,5)...(n?2,n) 做一次即可。
如果是偶數,就找到一段異或和為0的前綴,然后前后分別做即可。
如果找不到,序列就一定長成 10000...000110000...000110000...0001 的樣子,這個時候是無解的(樣例也已經給出)。
代碼
盡管正解非常好寫,但還是懶得寫了…
貼上我艱苦奮戰(zhàn)出的亂搞代碼:
#include<bits/stdc++.h>
using namespace std
;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std
;const int N
=3e5+100;
const int M
=2e5+100;
const int inf
=2e9+100;inline ll
read(){ll
x(0),f(1);char c
=getchar();while(!isdigit(c
)) {if(c
=='-')f
=-1;c
=getchar();}while(isdigit(c
)) {x
=(x
<<1)+(x
<<3)+c
-'0';c
=getchar();}return x
*f
;
}int n
,m
;
int a
[N
],ans
[N
],num
;
int s
[N
];
bool flag
;
inline int calc(int l
,int r
){assert(r
-l
+1==3);return a
[l
]^a
[l
+1]^a
[r
];
}
inline void rev(int l
,int r
){int o
=calc(l
,r
);for(int i
=l
;i
<=r
;i
++) a
[i
]=o
;ans
[++num
]=l
;
}void workl(int p
){if(p
==0) return;if(a
[p
]){if(a
[p
-1]) rev(p
-1,p
+1);else if(a
[p
-2]) rev(p
-2,p
);else{rev(p
-2,p
);rev(p
-1,p
+1);}}workl(p
-1);
}
void workr(int p
){if(p
==n
+1) return;if(a
[p
]){if(a
[p
+1]) rev(p
-1,p
+1);else if(a
[p
+2]) rev(p
,p
+2);else{rev(p
,p
+2);rev(p
-1,p
+1);}}workr(p
+1);
}bool find(int l
,int r
){if(calc(l
,r
)) return false;if(s
[l
-1]%2==0){rev(l
,r
);workl(l
-1);workr(r
+1);return true;}int x
=l
,y
=r
;while(l
>1&&a
[l
-1]==0) l
--;while(r
<n
&&a
[r
+1]==0) r
++;if((r
-l
+1)%2==1){rev(x
,y
);while(l
<=r
){rev(l
-1,l
+1);l
+=2;}workl(r
-2);workr(r
+2);return true;}if((r
-l
+1)%2==0&&l
-2>=1){if(a
[l
-2]==0){rev(l
-2,l
);l
++;}}if((r
-l
+1)%2==0&&r
+2<=n
){if(a
[r
+2]==0){rev(r
,r
+2);r
--;}}if((r
-l
+1)%2==1){while(l
<=r
){rev(l
-1,l
+1);l
+=2;}workl(r
-2);workr(r
+2);return true;}return false;
}
void work(){num
=0;flag
=0;int cnt(0);n
=read();for(int i
=1;i
<=n
;i
++){a
[i
]=read(),cnt
+=a
[i
];}if(cnt
&1){puts("NO");return;}for(int i
=1;i
+2<=n
;i
++){if(find(i
,i
+2)){flag
=1;break;}else if(a
[i
]&&!a
[i
+1])rev(i
,i
+2);s
[i
]=s
[i
-1]+a
[i
];}if(!flag
){for(int i
=1;i
+2<=n
;i
++){if(find(i
,i
+2)){flag
=1;break;}s
[i
]=s
[i
-1]+a
[i
];}}if(flag
){puts("YES");printf("%d\n",num
);for(int i
=1;i
<=num
;i
++) printf("%d ",ans
[i
]);puts("");}else puts("NO");
}
int clo
;
signed main(){
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint T
=read();while(T
--){work();}return 0;
}
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的# CF1572B Xor of 3(构造)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。