• 树链剖分【p1505】[国家集训队]旅游


    Description

    Ray 乐忠于旅游,这次他来到了T 城。T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接。为了方便游客到达每个景点但又为了节约成本,T 城的任意两个景点之间有且只有一条路径。换句话说, T 城中只有N − 1 座桥。

    Ray 发现,有些桥上可以看到美丽的景色,让人心情愉悦,但有些桥狭窄泥泞,令人烦躁。于是,他给每座桥定义一个愉悦度w,也就是说,Ray 经过这座桥会增加w 的愉悦度,这或许是正的也可能是负的。有时,Ray 看待同一座桥的心情也会发生改变。

    现在,Ray 想让你帮他计算从u 景点到v 景点能获得的总愉悦度。有时,他还想知道某段路上最美丽的桥所提供的最大愉悦度,或是某段路上最糟糕的一座桥提供的最低愉悦度。

    Input

    输入的第一行包含一个整数N,表示T 城中的景点个数。景点编号为 0...N − 1。

    接下来N − 1 行,每行三个整数u、v 和w,表示有一条u 到v,使 Ray 愉悦度增加w 的桥。桥的编号为1...N − 1。|w| <= 1000。 输入的第N + 1 行包含一个整数M,表示Ray 的操作数目。

    接下来有M 行,每行描述了一个操作,操作有如下五种形式:

    • C i w,表示Ray 对于经过第i 座桥的愉悦度变成了w。
    • N u v,表示Ray 对于经过景点u 到v 的路径上的每一座桥的愉悦度都变成原来的相反数。
    • SUM u v,表示询问从景点u 到v 所获得的总愉悦度。
    • MAX u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最大愉悦度。
    • MIN u v,表示询问从景点u 到v 的路径上的所有桥中某一座桥所提供的最小愉悦度。

    测试数据保证,任意时刻,Ray 对于经过每一座桥的愉悦度的绝对值小于等于1000。

    Output

    对于每一个询问(操作S、MAX 和MIN),输出答案。

    树剖裸题,边权转点权,直接赋给深度较深的点.

    查询的时候由于会出多修改一个点的问题,所以要(+1)

    这里把编号从(0)(n-1)变成了(1)(n).

    貌似这样会少很多锅?单点修改也要下放标记。怪不得一直Wa

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #define int long long
    #define ls o<<1
    #define rs o<<1|1
    #define N 1000080
    #define R register
    using namespace std;
    inline void in(int &x)
    {
    	int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    int n,head[N],tot,depth[N],size[N],f[N],son[N],val[N];
    struct cod{int u,v,w,fr;}edge[N<<1];
    int tr[N<<2],mn[N<<2],mx[N<<2],m,tg[N<<2];
    int dfn[N],fdfn[N],idx,top[N];
    char s[8];
    inline void add(int x,int y,int z)
    {
    	edge[++tot].u=head[x];
    	edge[tot].fr=x;
    	edge[tot].v=y;
    	edge[tot].w=z;
    	head[x]=tot;
    }
    inline void up(int o)
    {
    	tr[o]=tr[ls]+tr[rs];
    	mx[o]=max(mx[ls],mx[rs]);
    	mn[o]=min(mn[ls],mn[rs]);
    }
    inline void down(int o,int l,int r)
    {
    	if(tg[o])
    	{
    		tg[ls]^=1;tg[rs]^=1;
    		tr[ls]*=-1;tr[rs]*=-1;
    		swap(mx[ls],mn[ls]);swap(mx[rs],mn[rs]);
    		mx[ls]*=-1;mx[rs]*=-1;mn[ls]*=-1;mn[rs]*=-1;
    		tg[o]^=1;
    	}
    }
    void build(int o,int l,int r)
    {
    	if(l==r)
    	{
    		tr[o]=val[fdfn[l]];
    		mn[o]=mx[o]=tr[o];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	up(o);
    }
    void change(int o,int l,int r,int pos,int w)
    {
    	if(l==r){tr[o]=mx[o]=mn[o]=w;return;}
    	down(o,l,r);
    	int mid=(l+r)>>1;
    	if(pos<=mid)change(ls,l,mid,pos,w);
    	else change(rs,mid+1,r,pos,w);
    	up(o);
    }
    void qufan(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r)
    	{
    		tr[o]*=-1;tg[o]^=1;
    		swap(mx[o],mn[o]);
    		mx[o]*=-1;mn[o]*=-1;
    		return;
    	}
    	down(o,l,r);
    	int mid=(l+r)>>1;
    	if(x<=mid)qufan(ls,l,mid,x,y);
    	if(y>mid)qufan(rs,mid+1,r,x,y);
    	up(o);
    }
    int query_sum(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r)return tr[o];
    	down(o,l,r);
    	int mid=(l+r)>>1,res=0;
    	if(x<=mid)res+=query_sum(ls,l,mid,x,y);
    	if(y>mid) res+=query_sum(rs,mid+1,r,x,y);
    	return res;
    }
    int query_max(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r)return mx[o];
    	down(o,l,r);
    	int mid=(l+r)>>1,res=-214700483647LL;
    	if(x<=mid)res=max(res,query_max(ls,l,mid,x,y));
    	if(y>mid)res=max(res,query_max(rs,mid+1,r,x,y));
    	return res;
    }
    int query_min(int o,int l,int r,int x,int y)
    {
    	if(x<=l and y>=r)return mn[o];
    	down(o,l,r);
    	int mid=(l+r)>>1,res=214700483647LL;
    	if(x<=mid)res=min(res,query_min(ls,l,mid,x,y));
    	if(y>mid)res=min(res,query_min(rs,mid+1,r,x,y));
    	return res;
    }
    void dfs1(int u,int fa,int dis)
    {
    	depth[u]=depth[fa]+1;size[u]=1;f[u]=fa;val[u]=dis;
    	for(R int i=head[u];i;i=edge[i].u)
    	{
    		if(edge[i].v==fa)continue;
    		dfs1(edge[i].v,u,edge[i].w);
    		size[u]+=size[edge[i].v];
    		if(son[u]==-1 or size[son[u]]<size[edge[i].v])
    			son[u]=edge[i].v;
    	}
    }
    void dfs2(int u,int t)
    {
    	dfn[u]=++idx;fdfn[idx]=u;top[u]=t;
    	if(son[u]==-1)return;
    	dfs2(son[u],t);
    	for(R int i=head[u];i;i=edge[i].u)
    	{
    		if(dfn[edge[i].v])continue;
    		dfs2(edge[i].v,edge[i].v);
    	}
    }
    inline void tchange(int x,int y)
    {
    	int fx=top[x],fy=top[y];
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			qufan(1,1,idx,dfn[fx],dfn[x]);
    			x=f[fx];
    		}
    		else
    		{
    			qufan(1,1,idx,dfn[fy],dfn[y]);
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x == y) return ; 
    	if(dfn[x]>dfn[y])swap(x,y);
    	qufan(1,1,idx,dfn[x]+1,dfn[y]);
    }
    inline int tquery(int x,int y)
    {
    	int fx=top[x],fy=top[y],res=0;
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			res+=query_sum(1,1,idx,dfn[fx],dfn[x]);
    			x=f[fx];
    		}
    		else
    		{
    			res+=query_sum(1,1,idx,dfn[fy],dfn[y]);
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x == y) return res ; 
    	if(dfn[x]>dfn[y])swap(x,y);
    	res+=query_sum(1,1,idx,dfn[x]+1,dfn[y]);
    	return res;
    }
    inline int tquery_min(int x,int y)
    {
    	int fx=top[x],fy=top[y],res=214700483647LL;
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			res=min(res,query_min(1,1,idx,dfn[fx],dfn[x]));
    			x=f[fx];
    		}
    		else
    		{
    			res=min(res,query_min(1,1,idx,dfn[fy],dfn[y]));
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x == y) return res ; 
    	if(dfn[x]>dfn[y])swap(x,y);
    	res=min(res,query_min(1,1,idx,dfn[x]+1,dfn[y]));
    	return res;
    }
    inline int tquery_max(int x,int y)
    {
    	int fx=top[x],fy=top[y],res=-214700483647LL;
    	while(fx!=fy)
    	{
    		if(depth[fx]>depth[fy])
    		{
    			res=max(res,query_max(1,1,idx,dfn[fx],dfn[x]));
    			x=f[fx];
    		}
    		else
    		{
    			res=max(res,query_max(1,1,idx,dfn[fy],dfn[y]));
    			y=f[fy];
    		}
    		fx=top[x],fy=top[y];
    	}
    	if(x == y) return res ; 
    	if(dfn[x]>dfn[y])swap(x,y);
    	res=max(res,query_max(1,1,idx,dfn[x]+1,dfn[y]));
    	return res;
    }
    signed main()
    {
    	in(n);memset(son,-1,sizeof son);
    	for(R int i=1,x,y,z;i<n;i++)
    	{
    		in(x),in(y),in(z);
    		x++;y++;
    		add(x,y,z);add(y,x,z);
    	}
    	dfs1(1,0,0);dfs2(1,1);
    	build(1,1,n);
    	in(m);
    	for(R int x,y;m;m--)
    	{
    		scanf("%s",s);in(x),in(y);
    		if(s[0]=='C')
    		{
    			x*=2;
    			if(depth[edge[x].fr]>depth[edge[x].v])
    				x=edge[x].fr;
    			else x=edge[x].v;
    			change(1,1,idx,dfn[x],y);
    		}
    		else if(s[0]=='N'){x++,y++,tchange(x,y);}
    		else if(s[0]=='S'){x++,y++,printf("%lld
    ",tquery(x,y));}
    		else if(s[1]=='A'){x++,y++,printf("%lld
    ",tquery_max(x,y));}
    		else if(s[1]=='I'){x++,y++,printf("%lld
    ",tquery_min(x,y));}
    	}
    }
    
  • 相关阅读:
    C++泛型函数及模版类
    android逆向入门及工具下载
    排序算法之交换排序
    索尼法则=?职场法则
    2014年5月20日---一个值得纪念的日子
    C#的委托是什么?
    物联网RFID安全研究
    [转]nmap使用方法
    [转]中间人攻击-ARP毒化
    15019:Only the instance admin may alter the PermSize attribute
  • 原文地址:https://www.cnblogs.com/-guz/p/9797939.html
Copyright © 2020-2023  润新知