【HDU - 6186】CS Course(按位与,按位或,按位异或的区间统计,二进制拆位)
题干:
Little A has come to college and majored in Computer and Science.
Today he has learned bit-operations in Algorithm Lessons, and he got a problem as homework.
Here is the problem:
You are giving n non-negative integers a1,a2,⋯,ana1,a2,⋯,an, and some queries.
A query only contains a positive integer p, which means you
are asked to answer the result of bit-operations (and, or, xor) of all the integers except apap.
Input
There are no more than 15 test cases.
Each test case begins with two positive integers n and p
in a line, indicate the number of positive integers and the number of queries.
2≤n,q≤1052≤n,q≤105
Then n non-negative integers a1,a2,⋯,ana1,a2,⋯,an follows in a line, 0≤ai≤1090≤ai≤109 for each i in range[1,n].
After that there are q positive integers p1,p2,⋯,pqp1,p2,⋯,pqin q lines, 1≤pi≤n1≤pi≤n for each i in range[1,q].
Output
For each query p, output three non-negative integers indicates the result of bit-operations(and, or, xor) of all non-negative integers except apap in a line.
Sample Input
3 3
1 1 1
1
2
3
Sample Output
1 1 0
1 1 0
1 1 0
题目大意:
题意:给定n 个数和 q 个查询,qi 为查询数,求去掉下标为qi 的元素后其他元素 and , or , xor的结果。
解题报告:
这题也可以用线段树nlogn搞或者直接处理前缀后缀然后on搞(因为没有修改嘛)然后也可以按位统计然后nlogn乱搞。。
但是前者没法做带更新的,后者可以。
AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
int cnt[44];
ll a[MAX];
int n,q,p;
int main()
{
while(~scanf("%d%d",&n,&q)) {
memset(cnt,0,sizeof cnt);
ll Xor = 0;
for(int i = 1; i<=n; i++) scanf("%lld",a+i),Xor ^= a[i];
for(int i = 1; i<=n; i++) {
for(int j = 0; j<33; j++) {
cnt[j] += (a[i]>>j)&1;
}
}
while(q--) {
scanf("%d",&p);
ll And=0,Or=0,X;
ll tar = a[p];
X = Xor^tar;
for(int j = 0; j<33; j++) {
ll tmp = (tar>>j)&1;
if(cnt[j]-tmp>0) Or |= (1<<j);
if(cnt[j]-tmp == n-1) And |= (1<<j);
}
printf("%lld %lld %lld\n",And,Or,X);
}
}
return 0 ;
}
AC代码2:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mid ((st[id].l+st[id].r)>>1)
#define lson (id<<1)
#define rson ((id<<1)|1)
using namespace std;
const int N = 150000;
int arr[N];
struct Node{
int l, r, OR, XOR, AND;
}st[N<<3];
void build(int id, int l, int r)
{
st[id].l = l; st[id].r = r;
if(l == r){
st[id].OR = arr[l];
st[id].AND = arr[l];
st[id].XOR = arr[l];
return;
}
build(lson, l, mid);
build(rson, mid+1, r);
st[id].OR = st[lson].OR | st[rson].OR;
st[id].XOR = st[lson].XOR ^ st[rson].XOR;
st[id].AND = st[lson].AND & st[rson].AND;
}
int query(int id, int l, int r, int op){
if(st[id].l == l && st[id].r == r){
if(op == 1)return st[id].OR;
if(op == 2)return st[id].XOR;
if(op == 3)return st[id].AND;
}
if(l > mid)return query(rson, l, r, op);
else if(r <= mid)return query(lson, l, r, op);
else{
if(op == 1)return query(lson, l, mid, op) | query(rson, mid+1, r, op);
if(op == 2)return query(lson, l, mid, op) ^ query(rson, mid+1, r, op);
if(op == 3)return query(lson, l, mid, op) & query(rson, mid+1, r, op);
}
}
int main()
{
int n, q;
while(scanf("%d%d", &n, &q)!=EOF)
{
for(int i = 1; i <= n; i++)
scanf("%d", &arr[i]);
build(1, 1, n);
int p;
while(q--){
scanf("%d", &p);
if(p == 1)
printf("%d %d %d\n", query(1, 2, n, 3), query(1, 2, n, 1), query(1, 2, n, 2));
else if(p == n)
printf("%d %d %d\n", query(1, 1, n-1, 3), query(1, 1, n-1, 1), query(1, 1, n-1, 2));
else
printf("%d %d %d\n", query(1, 1, p-1, 3)&query(1, p+1, n, 3), query(1, 1, p-1, 1)|query(1, p+1, n, 1), query(1, 1, p-1, 2)^query(1, p+1, n, 2));
}
}
return 0;
}