uva Array Transformer
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3154
题意:给一个序列,然后是操作:
L,R,V,P:求区间[L,R]中小于V的个数k,然后更新 P位置的值为k*u/(R-L+1)。
输出最后的序列。
思路:线段树 套 sbt.
View Code
#include<stdio.h> #include<string.h> #include<iostream> #include<stdlib.h> #include<algorithm> using namespace std; #define LL long long const int maxn = 300005; int ch[maxn*25][2]; int sz[maxn*25]; LL val[maxn*25]; LL as[maxn]; LL bs[maxn]; int ds[maxn]; int tot; LL n,m,u; struct nd{ int rt; inline void clr(){rt=0;} inline void LRrot(int &x,int f) { int k = ch[x][!f]; ch[x][!f] = ch[k][f]; ch[k][f] = x; sz[k] = sz[x]; sz[x] = sz[ch[x][f]] + sz[ch[x][!f]] + 1; x = k; } //调整处理 void Maintain(int &r,bool flag) { if(flag){//更新右子树 if(sz[ch[ch[r][1]][1]] > sz[ch[r][0]]) LRrot(r,0); else if(sz[ch[ch[r][1]][0]] > sz[ch[r][0]]){ LRrot(ch[r][1],1); LRrot(r,0); }else return ; }else{//更新在左子树 if(sz[ch[ch[r][0]][0]] > sz[ch[r][1]]) LRrot(r,1); else if(sz[ch[ch[r][0]][1]] > sz[ch[r][1]]){ LRrot(ch[r][0],0); LRrot(r,1); }else return; } //更新子树,然后再更新根,直到平衡为止 Maintain(ch[r][0],false); Maintain(ch[r][1],true); Maintain(r,false); Maintain(r,true); } void Insert(int &r,LL k) { if(r==0){ r = ++tot; ch[r][0] = ch[r][1] = 0; sz[r] = 1; val[r] = k; }else{ sz[r]++; if(k<val[r]) Insert(ch[r][0],k); else Insert(ch[r][1],k); Maintain(r,k>=val[r]); } } int Remove(int &r,LL k) { int dval; if(!r)return 0; sz[r]--; if(val[r]==k||(ch[r][0]==0&&k<val[r])||(ch[r][1]==0&&k>val[r])){ dval = val[r]; if(ch[r][0]&&ch[r][1]) val[r] = Remove(ch[r][0],k+1); else r = ch[r][0]+ch[r][1]; }else dval = Remove(ch[r][k>val[r]],k); return dval; } int GetRank(int &r,LL k) { if(!r)return 0; if(k<val[r])return GetRank(ch[r][0],k); else if(k>=val[r]) return GetRank(ch[r][1],k)+sz[ch[r][0]] + 1; return sz[ch[r][0]]+1; } }T[maxn*4]; void build(int rt,int l,int r) { int md = (l + r)>> 1; T[rt].clr(); int j = 0; for(int i = l; i <= r; ++ i)bs[j++]=as[i]; sort(bs,bs+j); for(int i = j / 2; i < j; ++ i) T[rt].Insert(T[rt].rt,bs[i]); for(int i = 0; i < j / 2; ++ i) T[rt].Insert(T[rt].rt,bs[i]); if(l==r){ ds[l]=rt; return; } build(rt<<1,l,md); build(rt<<1|1,md+1,r); } int ans; void query(int rt,int l,int r,int L,int R,LL v) { int md = (l + r) >> 1; if(L<=l && r<=R){ ans += T[rt].GetRank(T[rt].rt,v); return; } if(L<=md)query(rt<<1,l,md,L,R,v); if(R>md )query(rt<<1|1,md+1,r,L,R,v); } void update(int rt,LL v,LL rv) { while(rt){ T[rt].Remove(T[rt].rt,rv); T[rt].Insert(T[rt].rt,v); rt /= 2; } } //下面分别是输入输出优化 inline int scan(){ int res=0,ch; while(!((ch=getchar())>='0' && ch<='9')) if(ch==EOF) return 1<<30; res=ch-'0'; while((ch=getchar())>='0' && ch<='9') res=res*10+(ch-'0'); return res; } inline void printf_(LL num){ bool flag=false; if(num<0){ putchar('-'); num=-num; } LL ans[30],top=0; while(num!=0){ ans[top++]=num%10; num/=10; } if(top==0) putchar('0'); for(int i=top-1;i>=0;i--){ char ch=ans[i]+'0'; putchar(ch); } puts(""); } int main() { LL i,l,r,p,v; // freopen("D:\\in.txt","r",stdin); // freopen("D:\\out1.txt","w",stdout); while(scanf("%lld %lld %lld",&n,&m,&u)==3){ for(i = 1; i <= n; ++ i)as[i]=scan(); tot = 0; build(1,1,n); for(i=0;i<m;++i){ l=scan();r=scan();v=scan();p=scan(); ans = 0; query(1,1,n,l,r,v-1); LL t = u * ans / (r - l + 1); // printf("-> %d %lld\n",ans,t); if(t^as[p]){ update(ds[p],t,as[p]); as[p] = t; } } for(i = 1; i <= n; ++ i)printf_(as[i]); } return 0; }
线段树 套 treap 卡死了。
YM刘汝佳
View Code
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<time.h> #define lowbit(x) (x)&(-x) #define LL long long using namespace std; const int maxn = 300005; LL val[maxn*23]; int ch[maxn*23][2]; int sz[maxn*23]; int cnt[maxn*23]; int fix[maxn*23]; int ds[maxn]; LL bs[maxn]; LL as[maxn],n,m,u; int size; LL f1,f2,f3,ans; struct treap{ int rt; inline void clr(){rt = -1;} inline void pushUp(int k){ if(k<0)return; sz[k] = cnt[k]; if(ch[k][0]!=-1)sz[k] += sz[ch[k][0]]; if(ch[k][1]!=-1)sz[k] += sz[ch[k][1]]; } inline void rot(int &x,int f){ LL y = ch[x][f]; ch[x][f] = ch[y][!f]; ch[y][!f] = x; pushUp(x); x = y; } inline void insert(int &k,LL v){ if(k==-1){ k = ++size; ch[k][0] = ch[k][1] = -1; val[k] = v; cnt[k] = 1; // f3=(f1+f2); // f1=f2;f2=f3; fix[k] = rand(); } else if(v < val[k]){ insert(ch[k][0],v); if(fix[ch[k][0]]>fix[ch[k][1]]) rot(k,0); } else{ insert(ch[k][1],v); if(fix[ch[k][1]]>fix[ch[k][0]]) rot(k,1); } pushUp(k); } inline void remove(int &k,LL v){ if(k==-1)return; if(v < val[k]) remove(ch[k][0],v); else if(v > val[k]) remove(ch[k][1],v); else{ if(ch[k][0]+ch[k][1]==-2) k = -1; else if(ch[k][0]==-1)k=ch[k][1]; else if(ch[k][1]==-1)k=ch[k][0]; else if(fix[ch[k][0]] < fix[ch[k][1]]){ rot(k,1); remove(ch[k][0],v); } else{ rot(k,0); remove(ch[k][1],v); } } pushUp(k); } inline void query(int k,LL v){ if(k<0)return; int kl = ch[k][0]; if(val[k]<=v){ ++ans; if(kl>-1) ans+=sz[kl]; } query(ch[k][val[k]<=v],v); } inline void debug(){ printf("rt %d\n",rt); Treaval(rt); } inline void Treaval(int x){ if(x>=0){ Treaval(ch[x][0]); printf("?áμ?%2d:×ó?ù×ó %2d óò?ù×ó %2d size = %2d ,val = %2lld\n",x,ch[x][0],ch[x][1],sz[x],val[x]); Treaval(ch[x][1]); } } }T[maxn*4]; void build(int rt,int l,int r) { int md = (l + r)>> 1; T[rt].clr(); int j = 0; for(int i = l; i <= r; ++ i)bs[j++]=as[i]; sort(bs,bs+j); for(int i = j / 2; i < j; ++ i) T[rt].insert(T[rt].rt,bs[i]); for(int i = 0; i < j / 2; ++ i) T[rt].insert(T[rt].rt,bs[i]); if(l==r){ ds[l]=rt; return; } build(rt<<1,l,md); build(rt<<1|1,md+1,r); } void query(int rt,int l,int r,int L,int R,LL v) { int md = (l + r) >> 1; if(L<=l && r<=R){ T[rt].query(T[rt].rt,v); return; } if(L<=md)query(rt<<1,l,md,L,R,v); if(R>md )query(rt<<1|1,md+1,r,L,R,v); } void update(int rt,LL v,LL rv) { while(rt){ if(rv<=1e9) T[rt].remove(T[rt].rt,rv); if(v<=1e9) T[rt].insert(T[rt].rt,v); rt /= 2; } } inline int scan(){ int res=0,ch; while(!((ch=getchar())>='0' && ch<='9')) if(ch==EOF) return 1<<30; res=ch-'0'; while((ch=getchar())>='0' && ch<='9') res=res*10+(ch-'0'); return res; } inline void printf_(LL num){ bool flag=false; if(num<0){ putchar('-'); num=-num; } LL ans[30],top=0; while(num!=0){ ans[top++]=num%10; num/=10; } if(top==0) putchar('0'); for(int i=top-1;i>=0;i--){ char ch=ans[i]+'0'; putchar(ch); } puts(""); } int main() { LL i,l,r,p,v,k; freopen("D:\\in.txt","r",stdin); freopen("D:\\out1.txt","w",stdout); while(scanf("%lld %lld %lld",&n,&m,&u)==3){ for(i = 1; i <= n; ++ i)as[i]=scan(); srand(time(0)); size = 1; f1=1000;f2=50000; build(1,1,n); for(i=0;i<m;++i){ l=scan();r=scan();v=scan();p=scan(); if(l>r)l^=r^=l^=r; ans = 0; query(1,1,n,l,r,v-1); LL t = u * ans / (r - l + 1); if(t^as[p]){ update(ds[p],t,as[p]); as[p] = t; } } for(i = 1; i <= n; ++ i)printf_(as[i]); } return 0; }

浙公网安备 33010602011771号