luogu的题面
https://www.luogu.org/problemnew/show/P3822
题意:
x初始为0,维护+a*2^k ,其中a为整数,k为自然数;查询x的第k位;
题解:
①将数看成序列,线段树逐位维护。比较大,压位(下面的代码base=30,ls() rs()为左右儿子)。
②输入1,a,b,即将b/base号节点加 (a<<b%base)的base位以内部分,b/base+1号节点加 (a<<b%base)base位以上的部分。
③假设我们已经找到了b对应的叶子节点,修改后考虑进位。定义fg1[k]表示k节点是否是最大值(1<<base)-1,b对应的叶子往上跳一层到k号节点,如果fg1[rs(k)]==false,直接rs(k)里进位就好了,否则把rs(k)清零,再往上跳,退位同理(写的时候记得pushdown和pushup 。。。。TAT);
1 #pragma GCC optimize(2) 2 #include<cstdio> 3 #include<iostream> 4 //#define N 1000100 5 //#define base 30 6 #define ll long long 7 #define ls(k) (k<<1) 8 #define rs(k) (ls(k)|1) 9 using namespace std; 10 const ll base=30,N=4.2e7/base,B=(1<<base)-1,len=4.1e7/base; 11 //const int B = (1<<base) - 1,len = 1e6 + 5; 12 int n,t1,t2,t3; 13 int w[N<<2],fg1[N<<2],fg0[N<<2],ly1[N<<2],ly0[N<<2]; 14 char gc(){ 15 static char *p1,*p2,s[1000000]; 16 if(p1==p2) p2=(p1=s)+fread(s,1,1000000,stdin); 17 return(p1==p2)?EOF:*p1++; 18 } 19 int rd(){ 20 int x = 0,f = 1; char c = gc(); 21 while(c<'0'||c>'9') {if(c=='-') f = -1; c = gc();} 22 while(c>='0'&&c<='9') {x = x * 10 + c - '0'; c = gc();} 23 return x * f; 24 } 25 void pushup(int k){ 26 int l = ls(k),r = rs(k); 27 fg0[k] = fg0[l] && fg0[r]; 28 fg1[k] = fg1[l] && fg1[r]; 29 } 30 void mdf(int k,int typ){ 31 w[k] = B * typ; 32 fg1[k] = ly1[k] = typ; 33 fg0[k] = ly0[k] = !typ; 34 } 35 void pushdown(int k){ 36 int l = ls(k),r = rs(k); 37 if(ly0[k]) mdf(l,0),mdf(r,0),ly0[k] = 0; 38 if(ly1[k]) mdf(l,1),mdf(r,1),ly1[k] = 0; 39 } 40 void change(int k,int l,int r,int typ){ 41 if(l==r) { 42 w[k]+=typ; 43 fg0[k] = !w[k]; 44 fg1[k] = (w[k]==B); 45 } 46 else{ 47 if(ly0[k]||ly1[k]) pushdown(k); 48 int mid = (l+r)>>1; 49 if(typ==1){ 50 if(!fg1[ls(k)]) change(ls(k),l,mid,1); 51 else mdf(ls(k),0),change(rs(k),mid+1,r,1); 52 } 53 else{ 54 if(!fg0[ls(k)]) change(ls(k),l,mid,-1); 55 else mdf(ls(k),1),change(rs(k),mid+1,r,-1); 56 } 57 pushup(k); 58 } 59 } 60 int update(int k,int l,int r,int x,int y){ 61 if(!y) return 0; 62 int typ = 0; 63 if(l==r) { 64 w[k] += y; 65 if(w[k]>=(1<<base)) w[k] -= (1<<base),typ = 1; 66 else if(w[k]<0) w[k] += (1<<base),typ = -1; 67 fg0[k] = !w[k]; 68 fg1[k] = (w[k]==B); 69 } 70 else { 71 if(ly0[k]||ly1[k]) pushdown(k); 72 int mid = (l + r)>>1; 73 if(x<=mid){ 74 typ = update(ls(k),l,mid,x,y); 75 if(typ==1) { 76 if(!fg1[rs(k)]) typ = 0,change(rs(k),mid+1,r,1); 77 else mdf(rs(k),0); 78 } 79 if(typ==-1){ 80 if(!fg0[rs(k)]) typ = 0,change(rs(k),mid+1,r,-1); 81 else mdf(rs(k),1); 82 } 83 } 84 else typ = update(rs(k),mid+1,r,x,y); 85 pushup(k); 86 } 87 return typ; 88 } 89 int query(int k,int l,int r,int x,int y){ 90 if(l==r) return bool(w[k]&y); 91 else { 92 if(ly0[k]||ly1[k]) pushdown(k); 93 int mid = (l + r)>>1; 94 if(x<=mid) return query(ls(k),l,mid,x,y); 95 else return query(rs(k),mid+1,r,x,y); 96 } 97 } 98 int main() 99 { //freopen("mzoj1111.in","r",stdin); 100 //freopen("mzoj1111.out","w",stdout); 101 n = rd(); t1 = rd(); t2 = rd(); t3 = rd(); 102 fg0[1] = ly0[1] = 1; 103 for(int i = 1;i <= n;i++){ 104 ll opt = rd(),f,a,b,x,y; 105 if(opt&1){ 106 a = rd(); b = rd(); 107 if(a<0) a*=-1,f=-1; else f=1; 108 a <<= (b%base); b /= base; 109 update(1,0,len,b,f*(a&B)); 110 update(1,0,len,b+1,f*(a>>base)); 111 } 112 else{ 113 x = rd(); 114 y = 1<<(x%base); x /= base; 115 int ans = query(1,0,len,x,y); 116 printf("%d ",ans); 117 } 118 } 119 return 0; 120 }//by tkys_Austin;