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;
}