打卡信奥刷题(1951)用C++实现信奥 P10307 「Cfz Round 2」Binary
摘要 题目P10307「Cfz Round 2」Binary要求计算满足f(u)=f(u+1)的整数u的数量,其中f(u)是u的二进制位对应数组元素的异或值。给定n+1个整数a0...an,需要输出答案的二进制形式(无前导零)。使用C++实现时,通过逐位异或处理,并利用二进制特性优化计算。多个测试用例需处理,注意边界条件如n=0时输出0。算法时间复杂度为O(n)每组数据,适用于大规模输入。
P10307 「Cfz Round 2」Binary
题目描述
给定 n + 1 n + 1 n+1 个整数 a 0 … a n a_0\dots a_n a0…an。
对于整数 u u u,设它在二进制下为 1 1 1 的位分别为 k 1 , k 2 … k m k_1, k_2\dots k_m k1,k2…km,那么它的权值 f ( u ) = a k 1 ⊕ a k 2 ⊕ ⋯ ⊕ a k m f(u) = a_{k_1} \oplus a_{k_2} \oplus \dots \oplus a_{k_m} f(u)=ak1⊕ak2⊕⋯⊕akm。此处的二进制位的编号从右到左,依次为 0 , 1 , 2 … 0,1,2\dots 0,1,2…。其中 ⊕ \oplus ⊕ 表示 按位异或 符号。
你想要知道有多少个 0 ≤ u ≤ 2 n − 1 0 \leq u \leq 2^n - 1 0≤u≤2n−1 使得 f ( u ) = f ( u + 1 ) f(u) = f(u + 1) f(u)=f(u+1)。为了方便,请你用 二进制形式 输出答案(不取模)。
请注意:输出不能包含前导 0 0 0,除非答案为 0 0 0。
输入格式
本题有多组测试数据。
第一行输入一个整数 T T T,表示测试数据组数。
接下来依次输入每组测试数据。对于每组测试数据:
- 第一行输入一个正整数 n n n。
- 第二行输入 n + 1 n + 1 n+1 个整数 a 0 … a n a_0 \dots a_n a0…an。
输出格式
对于每组数据,输出一行一个二进制整数,表示答案。
再次提示:输出不能包含前导 0 0 0,除非答案为 0 0 0。
输入输出样例 #1
输入 #1
5
2
0 1 2
3
1 3 3 1
4
2 2 5 4 2
5
7 0 3 4 0 1
6
5 2 1 8 6 0 9
输出 #1
10
1
100
11
0
说明/提示
「样例解释 #1」
对于第 1 1 1 组数据,
- ( 0 ) 10 = ( 0 ) 2 (0)_{10} = (0)_{2} (0)10=(0)2,所以 f ( 0 ) = 0 f(0) = 0 f(0)=0;
- ( 1 ) 10 = ( 1 ) 2 (1)_{10} = (1)_{2} (1)10=(1)2,所以 f ( 1 ) = a 0 = 0 f(1) = a_0 = 0 f(1)=a0=0;
- ( 2 ) 10 = ( 10 ) 2 (2)_{10} = (10)_{2} (2)10=(10)2,所以 f ( 2 ) = a 1 = 1 f(2) = a_1 = 1 f(2)=a1=1;
- ( 3 ) 10 = ( 11 ) 2 (3)_{10} = (11)_{2} (3)10=(11)2,所以 f ( 3 ) = a 0 ⊕ a 1 = 0 ⊕ 1 = 1 f(3) = a_0 \oplus a_1 = 0 \oplus 1 = 1 f(3)=a0⊕a1=0⊕1=1;
- ( 4 ) 10 = ( 100 ) 2 (4)_{10} = (100)_{2} (4)10=(100)2,所以 f ( 4 ) = a 2 = 2 f(4) = a_2 = 2 f(4)=a2=2。
这其中有 f ( 0 ) = f ( 1 ) f(0) = f(1) f(0)=f(1), f ( 2 ) = f ( 3 ) f(2) = f(3) f(2)=f(3),所以输出 ( 2 ) 10 = ( 10 ) 2 (2)_{10} = (10)_{2} (2)10=(10)2。
「数据范围」
设 ∑ n \sum n ∑n 表示单个测试点中 n n n 的和。
对于所有数据, 1 ≤ T ≤ 10 3 1 \leq T \leq 10^3 1≤T≤103, 1 ≤ n ≤ 2 × 10 5 1 \leq n \leq 2\times 10^5 1≤n≤2×105, ∑ n ≤ 6 × 10 5 \sum n \leq 6\times 10^5 ∑n≤6×105, 0 ≤ a i ≤ 2 30 − 1 0 \leq a_i \leq 2^{30} - 1 0≤ai≤230−1。
只有你通过本题的所有测试点,你才能获得本题的分数。
C++实现
#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &x){//快读
x=0;int f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
x*=f;
}
int t,n,s[200005],tmp;
bool ans[200005],fl;
int main(){
read(t);
for(;t--;){
read(n);tmp=0;
for(int i=0;i<=n;++i) read(s[i]);
for(int i=0;i<=n;++i){//计算答案
if(tmp==s[i]) ans[n-i]=1;
tmp^=s[i];
}
fl=0;
if(ans[0]){//特判
for(int i=1;i<=n+1;++i){
if(!ans[i]){
ans[i]=1;break;
}
ans[i]=0;
}
}
for(int i=n+1;i>0;--i){//输出
if(ans[i]) fl=1;//去除前导零
if(fl) cout<<ans[i];
ans[i]=0;//多测不清空,爆零两行泪
}ans[0]=0;//同上,很容易遗漏
if(!fl) cout<<0;//特判答案为零的情况
cout<<endl;
}
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐
所有评论(0)