http://www.lydsy.com/JudgeOnline/problem.php?id=1500 区间splay(调了一个小时是不是没救了)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int inf=5*(1e8); int read(){ char ch=getchar();int x=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } const int N=1000000+5; int fa[N],ch[N][2],mx[N],lx[N],rx[N],sum[N],set[N],rev[N],w[N],sz[N],cnt,root,seq[N]; bool tag[N]; queue<int>rab; int newid(){ if(rab.empty())return ++cnt; else{ int id=rab.front();rab.pop(); return id; } } void pushup(int x){ sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+w[x]; mx[x]=max(rx[ch[x][0]]+lx[ch[x][1]]+w[x],max(mx[ch[x][0]],mx[ch[x][1]])); lx[x]=max(lx[ch[x][0]],sum[ch[x][0]]+w[x]+lx[ch[x][1]]); rx[x]=max(rx[ch[x][1]],sum[ch[x][1]]+w[x]+rx[ch[x][0]]); sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; } void workset(int x){ w[x]=set[x];sum[x]=set[x]*sz[x];lx[x]=rx[x]=max(sum[x],0);mx[x]=max(w[x],sum[x]); } void workrev(int x){ swap(ch[x][0],ch[x][1]);swap(lx[x],rx[x]); } void pushdown(int x){ if(tag[x]){ if(ch[x][0])tag[ch[x][0]]=true,set[ch[x][0]]=set[x],workset(ch[x][0]); if(ch[x][1])tag[ch[x][1]]=true,set[ch[x][1]]=set[x],workset(ch[x][1]); tag[x]=0;rev[x]=0; } if(rev[x]){ rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; workrev(ch[x][0]);workrev(ch[x][1]); rev[x]=0; } } void rotate(int x,int &k){ int y=fa[x],z=fa[y],l=(ch[y][1]==x),r=l^1; if(y==k)k=x; else ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; pushup(y);pushup(x); } void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if(ch[y][0]==x^ch[z][0]==y)rotate(x,k); else rotate(y,k); } rotate(x,k); } } int kth(int x,int k){ pushdown(x); int r=sz[ch[x][0]]+1; //printf("%d %d %d %d %d %d\n",x,k,ch[x][0],ch[x][1],w[x],r); if(k==r)return x; else if(k<r)return kth(ch[x][0],k); else return kth(ch[x][1],k-r); } int split(int a,int b){ int x=kth(root,a),y=kth(root,b+2); splay(x,root);splay(y,ch[x][1]); return ch[y][0]; } void build(int &x,int l,int r){ if(l>r)return; int mid=l+r>>1;x=newid(); w[x]=seq[mid]; if(l==r){ mx[x]=sum[x]=seq[l]; lx[x]=rx[x]=max(seq[l],0); sz[x]=1; }else{ build(ch[x][0],l,mid-1);build(ch[x][1],mid+1,r); if(ch[x][0])fa[ch[x][0]]=x; if(ch[x][1])fa[ch[x][1]]=x; pushup(x); } } void del(int x){ if(!x)return; del(ch[x][0]);del(ch[x][1]); fa[x]=ch[x][0]=ch[x][1]=set[x]=rev[x]=0;tag[x]=0; rab.push(x); } void del(int pos,int tot){ int x=split(pos,pos+tot-1),y=fa[x],z=fa[y]; ch[y][0]=0;del(x); pushup(y);pushup(z); } void insert(int pos,int tot){ int x=kth(root,pos+1),y=kth(root,pos+2); splay(x,root);splay(y,ch[x][1]); for(int i=1;i<=tot;i++)seq[i]=read(); build(ch[y][0],1,tot);fa[ch[y][0]]=y; pushup(y);pushup(x); } void modify(int pos,int tot,int v){ int x=split(pos,pos+tot-1),y=fa[x],z=fa[y]; set[x]=v;tag[x]=true;workset(x); pushup(y);pushup(z); } void reverse(int pos,int tot){ int x=split(pos,pos+tot-1),y=fa[x],z=fa[y]; if(!tag[x]){ rev[x]^=1;workrev(x); pushup(y);pushup(z); } } int getsum(int pos,int tot){ int x=split(pos,pos+tot-1); return sum[x]; } int maxsum(){ return mx[root]; } void traversal(int x){ if(!x)return; pushdown(x); traversal(ch[x][0]); printf("%d %d %d %d\n",x,ch[x][0],ch[x][1],sz[x]); traversal(ch[x][1]); } void debug(){ traversal(root);putchar('\n'); } int main(){ //freopen("a.in","r",stdin); int n,m;n=read();m=read(); seq[1]=seq[n+2]=-inf;mx[0]=-inf; for(int i=2;i<=n+1;i++)seq[i]=read(); build(root,1,n+2); char op[20];int pos,tot,v; while(m--){ scanf("%s",op); if(op[2]=='X')printf("%d\n",maxsum()); else{ scanf("%d%d",&pos,&tot); if(op[2]=='S')insert(pos,tot); else if(op[2]=='L')del(pos,tot); else if(op[2]=='K'){ scanf("%d",&v); modify(pos,tot,v); }else if(op[2]=='V')reverse(pos,tot); else printf("%d\n",getsum(pos,tot)); } } return 0; }
http://poj.org/problem?id=2104 静态区间第K大,主席树
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define rep(i,l,r) for(int i=l;i<=r;i++) const int N=100000+5; const int M=3000000; struct Node{ int lc,rc,cnt; }tr[M]; int node; void insert(int &o,int l,int r,int v){ tr[++node]=tr[o];o=node; tr[o].cnt++; if(l==r)return; int mid=l+r>>1; if(v<=mid)insert(tr[o].lc,l,mid,v); else insert(tr[o].rc,mid+1,r,v); } int query(int x,int y,int l,int r,int k){ if(l==r)return l; int sum=tr[tr[y].lc].cnt-tr[tr[x].lc].cnt; int mid=l+r>>1; if(k<=sum)return query(tr[x].lc,tr[y].lc,l,mid,k); else return query(tr[x].rc,tr[y].rc,mid+1,r,k-sum); } int a[N],rk[N],b[N]; bool cmp(int i,int j){ return a[i]<a[j]; } int root[N]; int main(){ //freopen("a.in","r",stdin); int n,m;scanf("%d%d",&n,&m); rep(i,1,n)scanf("%d",&a[i]),rk[i]=i; sort(rk+1,rk+1+n,cmp); rep(i,1,n)b[rk[i]]=i; for(int i=1;i<=n;i++){ root[i]=root[i-1]; insert(root[i],1,n,b[i]); } while(m--){ int l,r,k;scanf("%d%d%d",&l,&r,&k); printf("%d\n",a[rk[query(root[l-1],root[r],1,n,k)]]); } return 0; }
http://uoj.ac/problem/3 link cut cactus tree
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<algorithm> using namespace std; #define rep(i,l,r) for(int i=l;i<=r;i++) const int N=150000+5; const int inf=1e9; int fa[N],ch[N][2],sz[N],mx[N],w[N]; bool rev[N]; int st[N],top; bool cmp(int i,int j){ return w[i]<w[j]; } bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void pushup(int x){ sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; mx[x]=max(x,max(mx[ch[x][0]],mx[ch[x][1]],cmp),cmp); } void pushdown(int x){ if(rev[x]){ rev[x]^=1;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); } } void rotate(int x){ int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1; if(!isroot(y))ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r];ch[x][r]=y; pushup(y);pushup(x); } void splay(int x){ st[++top]=x; for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i]; while(top)pushdown(st[top--]); while(!isroot(x)){ int y=fa[x],z=fa[y]; if(!isroot(y)){ if(ch[y][0]==x^ch[z][0]==y)rotate(x); else rotate(y); } rotate(x); } } void access(int x){ for(int t=0;x;t=x,x=fa[x]) splay(x),ch[x][1]=t,pushup(x); } void makeroot(int x){ access(x);splay(x);rev[x]^=1; } void link(int x,int y){ makeroot(x);fa[x]=y; } int split(int x,int y){ makeroot(x);access(y);splay(y); return y; } void cut(int x,int y){ split(x,y);ch[y][0]=fa[x]=0;pushup(y); } int pa[N]; int find(int x){ return pa[x]==x?x:pa[x]=find(pa[x]); } void merge(int x,int y){ x=find(x);y=find(y); if(x!=y)pa[x]=y; } int find(int x,int y){ return mx[split(x,y)]; } struct Edge{ int u,v,a,b; void init(){scanf("%d%d%d%d",&u,&v,&a,&b);} bool operator < (const Edge &rhs)const{ if(a==rhs.a)return b<rhs.b; return a<rhs.a; } }e[N]; int main(){ //freopen("a.in","r",stdin); int n,m;scanf("%d%d",&n,&m); rep(i,1,m)e[i].init(); sort(e+1,e+1+m); rep(i,1,m)w[i+n]=e[i].b,mx[i+n]=i+n; int ans=inf; rep(i,1,n)pa[i]=i; int tot=0; rep(i,1,m){ int x=find(e[i].u),y=find(e[i].v); if(x!=y)merge(x,y),tot++,link(e[i].u,i+n),link(i+n,e[i].v); else{ int t=find(e[i].u,e[i].v); if(w[t]>e[i].b){ cut(e[t-n].u,t);cut(e[t-n].v,t); link(e[i].u,i+n);link(e[i].v,i+n); } } if(find(1)==find(n))ans=min(ans,e[i].a+w[find(1,n)]); } if(ans==inf)ans=-1; printf("%d\n",ans); return 0; }
http://acm.hdu.edu.cn/showproblem.php?pid=1512 左偏树
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define rep(i,l,r) for(int i=l;i<=r;i++) const int N=100000+5; struct heapnode{ int l,r,v,d,f; }q[N]; int merge(int x,int y){ if(!x||!y)return x+y; if(q[x].v<q[y].v)swap(x,y); q[x].r=merge(q[x].r,y); q[q[x].r].f=x; if(q[q[x].l].d<q[q[x].r].d)swap(q[x].l,q[x].r); q[x].d=q[q[x].r].d+1; return x; } int find(int x){ return q[x].f==x?x:q[x].f=find(q[x].f); } int pop(int x){ int l=q[x].l,r=q[x].r; q[l].f=l;q[r].f=r; q[x].l=q[x].r=q[x].d=0; return merge(l,r); } int push(int x,int y){ return merge(x,y); } int main(){ //freopen("a.in","r",stdin); int n; while(~scanf("%d",&n)){ rep(i,1,n){ int val;scanf("%d",&val); q[i]=(heapnode){0,0,val,0,i}; } int m;scanf("%d",&m); int ans; while(m--){ int x,y;scanf("%d%d",&x,&y); x=find(x);y=find(y); if(x==y)ans=-1; else{ int u=pop(x);q[x].v/=2;u=push(u,x); int v=pop(y);q[y].v/=2;v=push(v,y); ans=q[merge(u,v)].v; } printf("%d\n",ans); } } return 0; }