模板复习计划——线性与半线性数据结构维护

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值