标签:
题目:要求支持带修改维护区间第k大的值。所谓的动态区间第k大。
思路:题解说的是树状数组套treap,然而没想通树状数组怎么维护。。。线段树的话就是把所有的值离散化一下,离线建个关于值的线段树,每个节点是一个treap,treap里的值用位置做关键字,然后做区间查询,复杂度是O(nlogn*logn)。基本也是经典的树套树做法。。。。然后赛后写了两遍都没过。。。。。今天心血来潮再挑战一下,结果从8点调到晚上1点。其间各种爆内存各种re各种t。。。。。随机数据对拍了好久没拍出问题来。。。。然后一直t,,后来突然想到改交vc,结果wa了。。。。然后搞了个数据,结果本地直接re。。简直凌乱了。。。然后随便试试把数组开大。。。结果就过了。。我草。。。明明g++开4e6都爆内存,vc开5e6居然还有富余。。。。然后再开个栈外挂,速度直逼标程。。。。
结论:这题有毒。。。。基本都是整体二分过的。。。有时间学习一下。。免得这么但疼。。。
/* * @author: Cwind * http://www.cnblogs.com/Cw-trip/ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #include <queue> #include <stack> #include <functional> #include <set> #include <cmath> using namespace std; #define IOS std::ios::sync_with_stdio(false);std::cin.tie(0) #define pb push_back #define PB pop_back #define fs first #define se second #define sq(x) (x)*(x) #define eps 0.00000001 #define IINF (1<<29) #define LINF (1ll<<59) typedef long long ll; typedef pair<int,int> pii; typedef pair<ll,ll> P; const int maxNode=5e6+300; struct treapNode{ treapNode *ch[2]; int right,val; int sz; treapNode():sz(0){} int cmp(int x) const { if(x==val) return -1; return x>val; } void maintain(){ sz=ch[0]->sz+ch[1]->sz+1; } }pool[maxNode]; int ph=0; treapNode *null=new treapNode(); treapNode *newtreapNode(int v){ treapNode *n=&pool[ph++]; n->val=v; n->right=rand(); n->ch[0]=n->ch[1]=null; return n; } void rotate(treapNode *&o,int d){ treapNode *k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o->maintain(); k->maintain(); o=k; } void insert(treapNode *&o,int x){ if(o==null) o=newtreapNode(x); else{ int d=o->val<x; insert(o->ch[d],x); if(o->ch[d]->right>o->right) rotate(o,d^1); } o->maintain(); } void remove(treapNode *&o,int x){ int d=o->cmp(x); if(d==-1){ if(o->ch[0]==null) o=o->ch[1]; else if(o->ch[1]==null) o=o->ch[0]; else{ int d2=o->ch[0]->right>o->ch[1]->right; rotate(o,d2); remove(o->ch[d2],x); } }else remove(o->ch[d],x); if(o!=null) o->maintain(); } int findless(treapNode *o,int x){ int r=0; while(o!=null){ if(o->val>x){ o=o->ch[0]; } else{ r+=o->ch[0]->sz+1; o=o->ch[1]; } } return r; } int culbetween(treapNode *o,int l,int r){ return findless(o,r)-findless(o,l-1); } int ah; const int maxn=1e6+3000; struct QU{ int t,a,b,c; }qu[maxn]; struct segNode{ int l,r; treapNode *root; segNode *ch[2]; }segpool[maxNode]; int segh=0; segNode *newsegNode(){ segNode *n=&segpool[segh++]; n->root=null; return n; } void buildSeg(segNode *n,int l,int r){ n->l=l,n->r=r; if(r-l<=1) return; n->ch[0]=newsegNode(); n->ch[1]=newsegNode(); buildSeg(n->ch[0],l,(l+r)/2); buildSeg(n->ch[1],(r+l)/2,r); } void segInsert(segNode *n,int x,int p){ int r=n->r,l=n->l; int mid=(r+l)/2; treapNode *&tn=n->root; insert(tn,p); if(r-l<=1) return; if(x>=mid) segInsert(n->ch[1],x,p); else segInsert(n->ch[0],x,p); } void segRemove(segNode *n,int x,int p){ int r=n->r,l=n->l; int mid=(r+l)/2; treapNode *&tn=n->root; remove(tn,p); if(r-l<=1) return; if(x>=mid) segRemove(n->ch[1],x,p); else segRemove(n->ch[0],x,p); } int segQuery(segNode *n,int a,int b,int k){ treapNode *tn=n->root; segNode *chl=n->ch[0],*chr=n->ch[1]; int l=n->l,r=n->r; if(r-l<=1) return l; int q1=culbetween(chl->root,a,b); if(q1>=k) return segQuery(chl,a,b,k); else return segQuery(chr,a,b,k-q1); } int N; int deca[maxn]; int idx(int x){ return lower_bound(deca,deca+ah,x)-deca; } segNode *segRoot; void clear(){ ph=0; segh=0; segRoot=newsegNode(); } int a[maxn]; template <class T> inline bool scan_d(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!=‘-‘&&(c<‘0‘||c>‘9‘)) c=getchar(); sgn=(c==‘-‘)?-1:1; ret=(c==‘-‘)?0:(c-‘0‘); while(c=getchar(),c>=‘0‘&&c<=‘9‘) ret=ret*10+(c-‘0‘); ret*=sgn; return 1; } inline void out(int x) { if(x>9) out(x/10); putchar(x%10+‘0‘); } int main(){ freopen("/home/slyfc/CppFiles/in","r",stdin); freopen("/home/slyfc/CppFiles/out","w",stdout); while(cin>>N){ clear(); for(int i=1;i<=N;i++){ scan_d(a[i]); deca[i-1]=a[i]; } int Q; scan_d(Q); int an=N; for(int i=1;i<=Q;i++){ int t; scan_d(t); if(t==1){ int l,v; scan_d(l);scan_d(v); qu[i].a=l,qu[i].b=v; deca[an++]=v; } else{ int l,r,k; scan_d(l);scan_d(r);scan_d(k); qu[i].a=l,qu[i].b=r,qu[i].c=k; } qu[i].t=t; } sort(deca,deca+an); ah=unique(deca,deca+an)-deca; buildSeg(segRoot,0,ah); for(int i=1;i<=N;i++) segInsert(segRoot,idx(a[i]),i); for(int i=1;i<=Q;i++){ if(qu[i].t==1){ int l=qu[i].a,v=qu[i].b; segRemove(segRoot,idx(a[l]),l); a[l]=v; segInsert(segRoot,idx(v),l); }else{ int l=qu[i].a,r=qu[i].b,k=qu[i].c; printf("%d\n",deca[segQuery(segRoot,l,r,k)]); } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/Cw-trip/p/4944071.html