Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<iostream>
- #include<vector>
- using namespace std;
- typedef long long ll;
- const ll pot = 1<<17;
- int n, q;
- vector<int> tree[(pot<<1)];
- vector<int> up_date[(pot<<1)];
- inline ll bit_to_int(vector<int> wiki)
- {
- ll wynik = 0;
- ll dodawacz = 1;
- for(ll e : wiki)
- {
- if(e)
- wynik += dodawacz;
- dodawacz<<=1;
- }
- return wynik;
- }
- inline vector<int> int_to_bit(ll li)
- {
- vector<int> ans;
- while(li)
- {
- ans.push_back(li&1);
- li>>=1;
- }
- return ans;
- }
- inline vector<int> add(int i, int j)
- {
- while(tree[i].size() < tree[j].size())
- tree[i].push_back(0);
- while(tree[j].size() < tree[i].size())
- tree[j].push_back(0);
- vector<int> ans;
- for(int x = 0; x < tree[i].size(); x++)
- ans.push_back(tree[i][x] + tree[j][x]);
- return ans;
- }
- inline vector<int> heal(vector<int> wiki)
- {
- vector<int> ans;
- int pom[100];
- for(int i = 0; i < 100; i++)
- pom[i] = 0;
- for(int i = 0; i < wiki.size(); i++)
- pom[i] = wiki[i];
- for(int i = 0; i < 100; i++)
- {
- ans.push_back(pom[i]&1);
- pom[i+1] += (pom[i]>>1);
- }
- return ans;
- }
- inline vector<int> xorens(vector<int> one, vector<int> two_x, ll ile)
- {
- vector<int> ans;
- while(one.size() < two_x.size())
- one.push_back(0);
- while(two_x.size() < one.size())
- two_x.push_back(0);
- for(int i = 0; i < one.size(); i++)
- {
- if(!two_x[i])
- ans.push_back(one[i]);
- if(two_x[i])
- ans.push_back(ile-one[i]);
- }
- return ans;
- }
- void update(int a, int b, int lo, int hi, int e, int val)
- {
- if(a == lo and b == hi)
- {
- tree[e] = xorens(tree[e], int_to_bit(val), hi-lo);
- up_date[e].push_back(val);
- return;
- }
- if(b <= a) return;
- int mid = (hi+lo)/2;
- if(up_date[e].size())
- {
- for(auto up : up_date[e])
- {
- tree[e<<1] = xorens(tree[e<<1], int_to_bit(up), (hi-lo)/2);
- up_date[e<<1].push_back(up);
- tree[(e<<1)+1] = xorens(tree[(e<<1)+1], int_to_bit(up), (hi-lo)/2);
- up_date[(e<<1)+1].push_back(up);
- }
- up_date[e].clear();
- }
- update(a, min(mid, b), lo, mid, e<<1, val);
- update(max(a, mid), b, mid, hi, (e<<1)+1, val);
- tree[e] = add(e<<1, (e<<1)+1);
- }
- ll query(int a, int b, int lo, int hi, int e)
- {
- if(a == lo and b == hi)
- return bit_to_int(heal(tree[e]));
- if(b <= a) return 0;
- int mid = (lo+hi)/2;
- if(up_date[e].size())
- {
- for(auto up : up_date[e])
- {
- tree[e<<1] = xorens(tree[e<<1], int_to_bit(up), (hi-lo)/2);
- up_date[e<<1].push_back(up);
- tree[(e<<1)+1] = xorens(tree[(e<<1)+1], int_to_bit(up), (hi-lo)/2);
- up_date[(e<<1)+1].push_back(up);
- }
- up_date[e].clear();
- }
- ll l = query(a, min(b, mid), lo, mid, e<<1);
- ll r = query(max(a, mid), b, mid, hi, (e<<1)+1);
- return l+r;
- }
- inline void init()
- {
- cin >> n;
- for(int i = 1; i <= n; i++)
- {
- ll x;
- cin >> x;
- tree[i+pot] = int_to_bit(x);
- }
- for(int i = pot-1; i; i--)
- tree[i] = add(i<<1, (i<<1)+1);
- cin >> q;
- }
- int main()
- {
- ios_base::sync_with_stdio(false);
- init();
- while(q--)
- {
- int co, a, b, w;
- cin >> co >> a >> b;
- if(co == 1)
- cout << query(a , b+1, 0, pot, 1) << "\n";
- if(co == 2)
- {
- cin >> w;
- update(a, b+1, 0, pot, 1, w);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement