Thuật toán IT trên bit.
Code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<set>
#include<vector>
#include<utility>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
using namespace std;
#define oo 1000000005
#define rep(i,s,e) for(int i = s; i < e; i++)
#define lop(i,s,e) for(int i = s; i != e; i++)
#define FOR(it,c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define SZ(x) ((int)(x).size())
#define X first
#define Y second
#define N 100005
typedef pair<int,int> II;
typedef pair<II,int> D;
typedef long long LL;
vector<int> V;
map<int,int> M;
set<int> S;
queue<int> Q;
stack<int> ST;
struct IT_Bit_Xor
{
bool rev[4 * N];
int val[4 * N];
void buil(int left, int right, int root, int *b)
{
rev[root] = 0;
if(left == right)
{
val[root] = b[left];
return;
}
int mid = (left + right) >> 1;
buil(left, mid, root << 1, b);
buil(mid + 1, right, (root << 1) + 1, b);
val[root] = val[root << 1] + val[(root << 1) + 1];
}
int get(int left, int right, int root)
{
if(!rev[root]) return val[root];
return (right - left + 1) - val[root];
}
void push(int left, int right, int root)
{
if(!rev[root]) return;
rev[root << 1] ^= 1;
rev[(root << 1) + 1] ^= 1;
rev[root] = 0;
}
void pull(int left, int right, int root)
{
int mid = (left + right) >> 1;
val[root] = get(left, mid, root << 1) + get(mid + 1, right, (root << 1) + 1);
}
int query(int left, int right, int root, int qleft, int qright)
{
if(qleft > right || qright < left) return 0;
if(qleft <= left && right <= qright) return get(left, right, root);
push(left, right, root);
int mid = (left + right) >> 1;
int _res = 0;
_res += query(left, mid, root << 1, qleft, qright);
_res += query(mid + 1, right, (root << 1) + 1, qleft, qright);
pull(left, right, root);
return _res;
}
void change(int left, int right, int root, int qleft, int qright)
{
if(qleft > right || qright < left) return;
if(qleft <= left && right <= qright)
{
rev[root] ^= 1;
return;
}
push(left, right, root);
int mid = (left + right) >> 1;
change(left, mid, root << 1, qleft, qright);
change(mid + 1, right, (root << 1) + 1, qleft, qright);
pull(left, right, root);
}
};
int n, m, a[N], b[N], t, l, r, x;
IT_Bit_Xor bit[20];
int getBit(int x,int i)
{
return ((x >> i) & 1);
}
int main()
{
#define Off true
if(Off)
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
}
cin >> n;
rep(i, 1, n + 1)
scanf("%d",&a[i]);
rep(i, 0, 20)
{
rep(j, 1, n + 1) b[j] = getBit(a[j],i);
bit[i].buil(1,n,1,b);
}
cin >> m;
rep(i,0,m)
{
scanf("%d",&t);
if(t == 1)
{
scanf("%d %d",&l,&r);
LL res = 0;
rep(i,0,20)
res += (1ll << i) * bit[i].query(1,n,1,l,r);
printf("%I64d\n",res);
}
else
{
scanf("%d %d %d",&l, &r, &x);
rep(i,0,20)
if(getBit(x,i)) bit[i].change(1,n,1,l,r);
}
}
return 0;
}
Không có nhận xét nào:
Đăng nhận xét