[BZOJ4942][Noi2017]整数 线段树+压位
用线段树来模拟加减法过程,维护连续一段中是否全为0/1。
因为数字很大,我们60位压一位来处理。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<cstdio> 6 #include<algorithm> 7 #define maxn 505050 8 #define base 60 9 #define ll long long 10 using namespace std; 11 inline ll read() { 12 ll x=0,f=1;char ch=getchar(); 13 for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; 14 for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; 15 return x*f; 16 } 17 ll n,m,S=(1ll<<60)-1; 18 struct Seg { 19 int al[2]; 20 ll tag,val; 21 }t[maxn*4]; 22 void put(int o,ll tmp) { 23 if(tmp!=-1) t[o].val=tmp; 24 if(tmp==0) {t[o].al[0]=1;t[o].al[1]=0;t[o].tag=tmp;} 25 else if(tmp==S) {t[o].al[0]=0;t[o].al[1]=1;t[o].tag=tmp;} 26 else {t[o].al[0]=t[o].al[1]=0;t[o].tag=tmp;} 27 } 28 void pushdown(int o) { 29 int ls=o<<1,rs=ls+1; 30 if(t[o].tag!=-1) {put(ls,t[o].tag);put(rs,t[o].tag);t[o].tag=-1;} 31 } 32 void pushup(int o) { 33 int ls=o<<1,rs=ls+1; 34 t[o].al[0]=t[ls].al[0]&t[rs].al[0]; 35 t[o].al[1]=t[ls].al[1]&t[rs].al[1]; 36 } 37 void build(int l,int r,int o) { 38 t[o].tag=-1,t[o].al[0]=1;t[o].al[1]=0;t[o].val=0; 39 if(l==r) return; 40 int mid=l+r>>1,ls=o<<1,rs=ls+1; 41 build(l,mid,ls);build(mid+1,r,rs); 42 } 43 ll query(int l,int r,int o,int x) { 44 if(l==r) return t[o].val; 45 pushdown(o); 46 int mid=l+r>>1,ls=o<<1,rs=ls+1; 47 if(x<=mid) return query(l,mid,ls,x); 48 else return query(mid+1,r,rs,x); 49 pushup(o); 50 } 51 void change(int l,int r,int o,int L,int R,ll tmp) { 52 if(L<=l&&R>=r) {put(o,tmp);return;} 53 pushdown(o); 54 int mid=l+r>>1,ls=o<<1,rs=ls+1; 55 if(L<=mid) change(l,mid,ls,L,R,tmp); 56 if(R>mid) change(mid+1,r,rs,L,R,tmp); 57 pushup(o); 58 } 59 int find(int l,int r,int o,int pos,int k) { 60 if(t[o].al[!k]) return -1; 61 if(l==r) return l; 62 int mid=l+r>>1,ls=o<<1,rs=ls+1; 63 pushdown(o); 64 if(pos<=mid) { 65 ll tmp=find(l,mid,ls,pos,k); 66 if(tmp!=-1) return tmp; 67 } 68 return find(mid+1,r,rs,pos,k); 69 pushup(o); 70 } 71 void add(int pos,ll ad) { 72 ll tmp=query(0,n,1,pos);change(0,n,1,pos,pos,(tmp+ad)&S); 73 if(tmp+ad>S) { 74 int l=find(0,n,1,pos+1,0); 75 tmp=query(0,n,1,l); 76 change(0,n,1,l,l,tmp+1); 77 if(pos+1<=l-1) change(0,n,1,pos+1,l-1,0); 78 } 79 } 80 void del(int pos,ll ad) { 81 ll tmp=query(0,n,1,pos); 82 if(tmp-ad<0) change(0,n,1,pos,pos,(S+tmp-ad+1)&S); 83 else change(0,n,1,pos,pos,(tmp-ad)&S); 84 if(tmp-ad<0) { 85 int l=find(0,n,1,pos+1,1); 86 tmp=query(0,n,1,l); 87 change(0,n,1,l,l,tmp-1); 88 if(pos+1<=l-1) change(0,n,1,pos+1,l-1,S); 89 } 90 } 91 int main() { 92 m=read();read();read();read();n=500005;build(0,n,1); 93 for(int i=1;i<=m;i++) { 94 int tp=read(); 95 if(tp==1) { 96 ll a=read(),b=read(); 97 if(a>0) { 98 ll p=b/base,q=b%base; 99 ll x=(a<<q)&S;add(p,x); 100 a>>=base-q;add(p+1,a); 101 } 102 else { 103 a=-a;ll p=b/base,q=b%base; 104 ll x=(a<<q)&S;del(p,x); 105 a>>=base-q;del(p+1,a); 106 } 107 } 108 else { 109 ll a=read(); 110 printf("%lld\n",(query(0,n,1,a/base)>>(a%base))&1); 111 } 112 } 113 } 114 /* 115 10 3 1 2 116 1 100 0 117 1 2333 0 118 1 -233 0 119 2 5 120 2 7 121 2 15 122 1 5 15 123 2 15 124 1 -1 12 125 2 15 126 */
O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~