ICPC2020 南京J 吉司機線段樹
阿新 • • 發佈:2022-12-13
題目是一個序列。
兩個操作 1 對L,R裡的所有數字對輸入x取max。
2 詢問L,R裡某一位二進位制位的1的個數。
n是正常的200000
用線段樹來維護兩個操作。先考慮第一個操作用吉司機樹的做法維護一個最小值m 最小值次數mn 次小值s。
這樣當x來到某個區間若m>=x就直接跳過了若mn>=x就可以直接把最小值修改掉打上標記。反之暴力向下遞迴。
容易想到這樣做複雜度是有保證的。
對於操作2維護區間每一位1的個數即可,對於操作1的修改這個陣列也很容易維護出來。
END.
code
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<ctime> #include<cctype> #include<queue> #include<deque> #include<stack> #include<iostream> #include<iomanip> #include<cstdio> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<cctype> #include<cstdlib> #include<queue> #include<deque> #include<stack> #include<vector> #include<algorithm> #include<utility> #include<bitset> #include<set> #include<map> #define ll long long #define db double #define INF 1100000000 #define inf 100000000000000000ll #define ldb long double #define pb push_back #define put_(x) printf("%d ",x); #define get(x) x=read() #define putl(x) printf("%lld\n",x) #define rep(p,n,i) for(int i=p;i<=n;++i) #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]]) #define pii pair<int,int> #define mk make_pair #define P 1000000007ll #define gf(x) scanf("%lf",&x) #define pf(x) ((x)*(x)) #define uint unsigned long long #define ui unsigned #define sq sqrt #define l(w) t[w].l #define r(w) t[w].r #define m(w) t[w].m #define mn(w) t[w].mn #define c(w) t[w].c #define s(w) t[w].s #define tag(w) t[w].tag #define S second #define mod 1000000007 #define sc(A) scanf("%d",&A) #define scs(A) scanf("%s",A); #define put(A) printf("%d\n",A) #define min(x,y) (x>=y?y:x) #define max(x,y) (x>=y?x:y) #define zz p<<1 #define yy p<<1|1 using namespace std; const int MAXN=200010,maxn=1000010; int n,q; int a[MAXN]; struct wy { int l,r; int m,c,mn; int s,tag; int b[32]; }t[MAXN<<2]; inline void pushup(int p) { if(m(zz)==m(yy)) { m(p)=m(zz); c(p)=c(zz)+c(yy); mn(p)=min(mn(zz),mn(yy)); } else { if(m(zz)<m(yy)) { m(p)=m(zz); c(p)=c(zz); mn(p)=min(mn(zz),m(yy)); } else { m(p)=m(yy); c(p)=c(yy); mn(p)=min(mn(yy),m(zz)); } } s(p)=s(zz)^s(yy); rep(0,29,i)t[p].b[i]=(t[zz].b[i]+t[yy].b[i]); } inline void build(int p,int l,int r) { l(p)=l;r(p)=r; tag(p)=-1; if(l==r) { m(p)=a[l]; mn(p)=INF; c(p)=1; s(p)=a[l]; rep(0,29,i)t[p].b[i]=(a[l]>>i)&1; return; } int mid=(l+r)>>1; build(zz,l,mid); build(yy,mid+1,r); pushup(p); } inline void pushdown(int p) { int x=tag(p);tag(p)=-1; if(m(zz)>=x); else { rep(0,29,i)t[zz].b[i]+=(((x>>i)&1)-((m(zz)>>i)&1))*c(zz); if(c(zz)&1)s(zz)=s(zz)^m(zz)^x; m(zz)=x;tag(zz)=x; } if(m(yy)>=x); else { rep(0,29,i)t[yy].b[i]+=(((x>>i)&1)-((m(yy)>>i)&1))*c(yy); if(c(yy)&1)s(yy)=s(yy)^m(yy)^x; m(yy)=x;tag(yy)=x; } } inline void modify(int p,int l,int r,int x) { if(l<=l(p)&&r>=r(p)) { if(m(p)>=x)return;//最小值大於x if(mn(p)>=x)//次小值大於x { rep(0,29,i)t[p].b[i]+=(((x>>i)&1)-((m(p)>>i)&1))*c(p); if(c(p)&1)s(p)=s(p)^m(p)^x; m(p)=x; tag(p)=x; return; } } int mid=(l(p)+r(p))>>1; if(tag(p)!=-1)pushdown(p); if(l<=mid)modify(zz,l,r,x); if(r>mid)modify(yy,l,r,x); pushup(p); } inline int ask(int p,int l,int r) { if(l<=l(p)&&r>=r(p))return s(p); int mid=(l(p)+r(p))>>1; if(tag(p)!=-1)pushdown(p); if(r<=mid)return ask(zz,l,r); if(l>mid)return ask(yy,l,r); return ask(zz,l,r)^ask(yy,l,r); } inline int ask(int p,int l,int r,int x) { if(l<=l(p)&&r>=r(p))return t[p].b[x]; int mid=(l(p)+r(p))>>1; if(tag(p)!=-1)pushdown(p); if(r<=mid)return ask(zz,l,r,x); if(l>mid)return ask(yy,l,r,x); return ask(zz,l,r,x)+ask(yy,l,r,x); } int main() { // freopen("1.in","r",stdin); sc(n);sc(q); rep(1,n,i)sc(a[i]); build(1,1,n); rep(1,q,i) { int op,l,r,x; sc(op);sc(l);sc(r);sc(x); if(op==1)modify(1,l,r,x); else { int ww=ask(1,l,r)^x; if(!ww){put(0);continue;} int cc; rep(0,29,j)if((ww>>j)&1)cc=j; //put(cc); put(ask(1,l,r,cc)+((x>>cc)&1)); } } //rep(1,n,i)put_(ask(1,i,i)); return 0; }