NC214618. 位运算
描述
鹏神通过高考考到了长沙学院,在一节程序设计课上学习了位运算,课后老师布置了一道作业题:
给你n个非负整数a1,a2,⋯,an。随后会问你q个问题,每个问题只包含一个正整数x,要求你计算除了第x个数外数组中其余数的按位与、按位或和按位异或的值。
输入描述
第一行一个正整数T表示测试数据组数(1≤T≤15)。
对于每一组测试数据第一行为两个正整数n和q,n表示数组的长度,q表示询问次数(2≤n,q≤105)。
第二行为n个非负整数a1,a2,⋯,an(0≤ai≤109)。
接下来q行,每行输入一个正整数x(1≤x≤n)。
输出描述
输出q行,每一行输出三个非负整数,表示数组中除第x个数外其余数的按位与、按位或和按位异或。
示例1
输入:
1 3 3 1 1 1 1 2 3
输出:
1 1 0 1 1 0 1 1 0
C(clang11) 解法, 执行用时: 77ms, 内存消耗: 7112K, 提交时间: 2021-03-10 11:08:47
#include<stdio.h> #include<string.h> int sum1[100050],sum2[100050],a[100050],sum3[100050],sum4[100050]; //sum[1],sum[2]分别为&的前缀和,后缀和。sum[3],sum[4]分别为|的前缀和后缀和。 int main() { int t,x,i; scanf("%d",&t); while(t--) { int n,q,sum=0; scanf("%d%d",&n,&q); for(i=1; i<=n; i++) { scanf("%d",&a[i]); sum^=a[i]; if(i==1){ sum1[i]=a[i]; sum3[i]=a[i]; } else { sum1[i]=a[i]&sum1[i-1]; sum3[i]=a[i]|sum3[i-1]; } } for(i=n; i>=1; i--) { if(i==n){ sum2[i]=a[i]; sum4[i]=a[i]; } else { sum2[i]=a[i]&sum2[i+1]; sum4[i]=a[i]|sum4[i+1]; } } while(q--){ scanf("%d",&x); if(x==1)printf("%d %d %d\n",sum2[x+1],sum4[x+1],sum^a[x]); else if(x==n)printf("%d %d %d\n",sum1[x-1],sum3[x-1],sum^a[x]); else printf("%d %d %d\n",sum1[x-1]&sum2[x+1],sum3[x-1]|sum4[x+1],sum^a[x]); } } return 0; }
C++ 解法, 执行用时: 68ms, 内存消耗: 5720K, 提交时间: 2021-06-24 21:13:17
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+7; int p[maxn]; int a[maxn],b[maxn],c[maxn]; int A[maxn],B[maxn],C[maxn]; int T; int n,q,x,res; int main() { ios::sync_with_stdio(false);cin.tie(0); cin>>T; while(T--) { cin>>n>>q; a[0]=1,b[0]=0,c[0]=0; A[n+1]=1,B[n+1]=0,C[n+1]=0; for(int i=1;i<=n;i++)cin>>p[i]; for(int i=1;i<=n;i++) { a[i]=p[i]&a[i-1]; b[i]=p[i]|b[i-1]; c[i]=p[i]^c[i-1]; } for(int i=n;i>=1;i--) { A[i]=p[i]&A[i+1]; B[i]=p[i]|B[i+1]; C[i]=p[i]^C[i+1]; } for(int i=1;i<=q;i++) { cin>>x; printf("%d %d %d\n",a[x-1]&A[x+1],b[x-1]|B[x+1],c[x-1]^C[x+1]); } } }