vjudge 數據結構 刷題記錄

hdu4010

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<stack>
using namespace std;
const int N=300005;

int n,q;
int u[N],v[N];
int fa[N],ch[N][2],w[N],rev[N],add[N],mx[N];
stack<int> s;
bool isroot(int u)
{
	return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
void up(int u)
{
	mx[u]=w[u];
	if (ch[u][0]&&mx[ch[u][0]]>mx[u]) mx[u]=mx[ch[u][0]];
	if (ch[u][1]&&mx[ch[u][1]]>mx[u]) mx[u]=mx[ch[u][1]];
}
void down(int u)
{
	int l=ch[u][0],r=ch[u][1];
	if (rev[u])
	{
		rev[u]^=1,rev[l]^=1,rev[r]^=1;
		swap(ch[u][0],ch[u][1]);
	}
	if (add[u])
	{
		add[l]+=add[u],add[r]+=add[u];
		mx[l]+=add[u],mx[r]+=add[u];
		w[l]+=add[u],w[r]+=add[u];
		add[u]=0;
	}
}
void rot(int x)
{
	int y=fa[x],z=fa[y],l,r;
	if (ch[y][0]==x) l=0;else l=1;r=l^1;
	if (!isroot(y))
		if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
	fa[x]=z,fa[y]=x,fa[ch[x][r]]=y;
	ch[y][l]=ch[x][r];ch[x][r]=y;
	up(y);
}
void splay(int x)
{
	int y=x,z;
	while (!isroot(y)) s.push(y),y=fa[y];s.push(y);
	while (!s.empty()) down(s.top()),s.pop();
	
	while (!isroot(x))
	{
		y=fa[x],z=fa[y];
		if (!isroot(y))
			if (ch[y][0]==x^ch[z][0]==y) rot(x);else rot(y);
		rot(x);
	}
	up(x);
}
void access(int x)
{
	int t=0;
	while (x)
	{
		splay(x);down(x);
		ch[x][1]=t;up(x);
		t=x,x=fa[x];
	}
}
void to_rt(int x)
{
	access(x);splay(x);rev[x]^=1;
}
void link(int u,int v)
{
	to_rt(u);fa[u]=v;
}
int find(int u)
{
	access(u);splay(u);
	while (ch[u][0]) u=ch[u][0];
	return u;
}
void Add()
{
	int u,v;
	scanf("%d%d",&u,&v);
	int fu=find(u),fv=find(v);
	if (fu==fv) {printf("-1\n");return;}
	link(u,v);
}
void del()
{
	int u,v;
	scanf("%d%d",&u,&v);
	int fu=find(u),fv=find(v);
	if (fu!=fv||u==v) {printf("-1\n");return;}
	to_rt(u),access(v),splay(v);
	fa[ch[v][0]]=0,ch[v][0]=0;up(v);
}
void add_val()
{
	int u,v,ww;
	scanf("%d%d%d",&ww,&u,&v);
	int fu=find(u),fv=find(v);
	if (fu!=fv) {printf("-1\n");return;}
	to_rt(u);access(v);splay(v);
	add[v]+=ww;w[v]+=ww;mx[v]+=ww;//在做標記的時候,不能只給標記數組更新,答案數組,權值數組相關的都要更新
}
void find_mx()
{
	int u,v,w;
	scanf("%d%d",&u,&v);
	int fu=find(u),fv=find(v);
	if (fu!=fv) {printf("-1\n");return;}
	to_rt(u),access(v),splay(v);
	printf("%d\n",mx[v]);
}

void work()
{
	memset(fa,0,sizeof(fa));
	memset(ch,0,sizeof(ch));
	memset(rev,0,sizeof(rev));
	memset(add,0,sizeof(add));
	memset(mx,0,sizeof(mx));
	
	for (int i=1;i<n;i++) scanf("%d%d",&u[i],&v[i]);
	for (int i=1;i<=n;i++) scanf("%d",&w[i]),mx[i]=w[i];
	for (int i=1;i<n;i++) link(u[i],v[i]);
	
	scanf("%d",&q);
	int opt;
	while (q--)
	{
		scanf("%d",&opt);
		switch(opt)
		{
			case 1:Add();break;
			case 2:del();break;
			case 3:add_val();break;
			case 4:find_mx();break;
		}
	}
	printf("\n");
}

int main()
{
	int T;
	while (~scanf("%d",&n)) work();
	return 0;
}

 spoj  Query on a tree

You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

We will ask you to perfrom some instructions of the following form:

  • CHANGE i ti : change the cost of the i-th edge to ti
    or
  • QUERY a b : ask for the maximum edge cost on the path from node a to node b

 

lct處理邊權:化邊爲點,化邊權爲點權

 

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<stack>
using namespace std;
const int N=20005;
const int inf=0x3f3f3f3f;

struct aa
{
	int u,v,c;
}bian[N];

stack<int> s;
int n,m;
int val[N],mx[N],fa[N],ch[N][2],rev[N];
void up(int x)
{
	mx[x]=val[x];
	if (ch[x][0]&&mx[ch[x][0]]>mx[x]) mx[x]=mx[ch[x][0]];
	if (ch[x][1]&&mx[ch[x][1]]>mx[x]) mx[x]=mx[ch[x][1]];
}
void down(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]);
	}
}
bool isroot(int u)
{
	return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
void rot(int x)  
{  
    int y=fa[x],z=fa[y],l,r;  
    if (ch[y][0]==x) l=0;else l=1;r=l^1;  
    if (!isroot(y))  
        if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;  
    fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;  
    ch[y][l]=ch[x][r];ch[x][r]=y;  
    up(y);    
}  
void splay(int x)  
{  
    int y=x,z;  
    while (!isroot(y)) s.push(y),y=fa[y];s.push(y);  
    while (!s.empty()) down(s.top()),s.pop();  
      
    while (!isroot(x))  
    {  
        y=fa[x],z=fa[y];  
        if (!isroot(y))  
            if (ch[z][0]==y^ch[y][0]==x) rot(x);else rot(y);  
        rot(x);   
    }  
    up(x);  
}  
void access(int x)
{
	int t=0;
	while (x)
	{
		splay(x);down(x);
		ch[x][1]=t;up(x);
		t=x;x=fa[x];
	}
}
void to_rt(int u)
{
	access(u);splay(u);rev[u]^=1;
}
void link(int u,int v)
{
	to_rt(u);fa[u]=v;
}
void work()
{
	memset(fa,0,sizeof(fa));
	memset(ch,0,sizeof(ch));
	memset(rev,0,sizeof(rev));
	memset(val,-inf,sizeof(val));
	int u,v,c;
	scanf("%d",&n);
	for (int i=1;i<n;i++)
	{
		scanf("%d%d%d",&bian[i].u,&bian[i].v,&bian[i].c);
		mx[i+n]=val[i+n]=bian[i].c;
		link(i+n,bian[i].u);
		link(i+n,bian[i].v);//以邊做點
	}
	char ch[11];
	do
	{
		scanf("%s",ch);
		if (ch[0]=='D') break;
		if (ch[0]=='C')
		{
			scanf("%d%d",&u,&c);
			splay(u+n);val[u+n]=c;up(u+n);
		}
		else 
		{
			scanf("%d%d",&u,&v);
			to_rt(u);access(v);splay(v);
			printf("%d\n",mx[v]);
		}
	}while(true); 
}

int main()
{
	int T;
	scanf("%d",&T);
	while (T--) work();
	return 0;
}


lct版 bzoj1036 樹的統計

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<stack>
using namespace std;
const int N=100005;

int n,q;
int u[N],v[N];

int fa[N],ch[N][2],rev[N],sum[N],mx[N],w[N];
bool isroot(int u)
{
	return ch[fa[u]][0]!=u&&ch[fa[u]][1]!=u;
}
void up(int x)
{
	int l=ch[x][0],r=ch[x][1];
	mx[x]=sum[x]=w[x];
	if (l)
	{
		mx[x]=max(mx[x],mx[l]);
		sum[x]+=sum[l];
	}
	if (r)
	{
		mx[x]=max(mx[x],mx[r]);
		sum[x]+=sum[r];
	}
}
void down(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 rot(int x)
{
	int y=fa[x],z=fa[y],l,r;
	if (ch[y][0]==x) l=0;else l=1;r=l^1;
	if (!isroot(y))
		if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;
	fa[x]=z,fa[y]=x,fa[ch[x][r]]=y;
	ch[y][l]=ch[x][r],ch[x][r]=y;
	up(y);
}
stack<int> s;
void splay(int x)
{
	int y=x,z;
	while (!isroot(y)) s.push(y),y=fa[y];s.push(y);
	while (!s.empty()) down(s.top()),s.pop();
	
	while (!isroot(x))
	{
		y=fa[x],z=fa[y];
		if (!isroot(y))	
			if (ch[y][0]==x^ch[z][0]==y) rot(x);else rot(y);
		rot(x);
	}
	up(x);
}
void access(int x)
{
	int t=0;
	while (x)
	{
		splay(x);down(x);
		ch[x][1]=t;up(x);
		t=x,x=fa[x];
	}
}
void to_rt(int u)
{
	access(u),splay(u),rev[u]^=1;
}
void link(int u,int v)
{
	to_rt(u);fa[u]=v;
}


int main()
{
	scanf("%d",&n);
	for (int i=1;i<n;i++) scanf("%d%d",&u[i],&v[i]);
	for (int i=1;i<=n;i++) scanf("%d",&w[i]),mx[i]=sum[i]=w[i];
	for (int i=1;i<n;i++) link(u[i],v[i]);
	scanf("%d",&q);
	char ch[11];
	int x,t;
	while (q--)
	{
		scanf("%s",ch);
		if (ch[1]=='H')
		{
			scanf("%d%d",&x,&t);
			splay(x);w[x]=t;up(x);
		}
		else 
		if (ch[1]=='M')
		{
			scanf("%d%d",&x,&t);
			to_rt(x),access(t),splay(t);
			printf("%d\n",mx[t]);
		}
		else 
		{
			scanf("%d%d",&x,&t);
			to_rt(x),access(t),splay(t);
			printf("%d\n",sum[t]);
		}
	}
	return 0;
}



 hdu3635  並查集

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=10005;

int n,q;
int fa[N],dep[N],size[N];
int find(int u)
{
	if (u==fa[u]) return u;
	int anc=find(fa[u]);
	dep[u]+=dep[fa[u]];
	fa[u]=anc;
	return anc;
}

void work()
{
	scanf("%d%d",&n,&q);
	for (int i=1;i<=n;i++) fa[i]=i,dep[i]=0,size[i]=1;
	char ch[2];
	int u,v,fu,fv;
	for (int i=1;i<=q;i++)
	{
		scanf("%s",ch);
		if (ch[0]=='T')
		{
			scanf("%d%d",&u,&v);
			fu=find(u),fv=find(v);
			dep[fu]=1,fa[fu]=fv,size[fv]+=size[fu];
		}
		else 
		{
			scanf("%d",&u);
			v=find(u);
			printf("%d %d %d\n",v,size[v],dep[u]);
		}
	}
}

int main()
{
	int T;
	scanf("%d",&T);
	for (int i=1;i<=T;i++) 
	{
		printf("Case %d:\n",i);
		work();
	}
	return 0;
}


 

 

發佈了98 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章