zoukankan      html  css  js  c++  java
  • Jzoj3625 旅行(travel)

    非常好的树剖模板题了,直接C颗线段树上去就好了,动态开点一次写对~

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 100010
    #define mid (l+r>>1)
    using namespace std;
    struct edge{ int v,nt; } G[200010];
    struct nod{ int l,r,s,m; } s[3000010];
    int h[N],sz[N],top[N],son[N],f[N],d[N];
    int n,m,cnt=1,tot=0,clk=0,w[N],l[N],c[N],rt[N];
    inline void gmax(int& x,int y){ x<y?x=y:0; }
    inline void ps(nod& x){
    	x.s=s[x.l].s+s[x.r].s;
    	x.m=max(s[x.l].m,s[x.r].m);
    }
    inline void adj(int x,int y){ 
    	G[++cnt]=(edge){y,h[x]}; h[x]=cnt;
    	G[++cnt]=(edge){x,h[y]}; h[y]=cnt;
    }
    void dfs(int x,int p){
    	d[x]=d[p]+1; sz[x]=1; f[x]=p;
    	for(int v,i=h[x];i;i=G[i].nt)
    		if(!d[v=G[i].v]){
    			dfs(v,x); sz[x]+=sz[v];
    			if(sz[v]>sz[son[x]]) son[x]=v;
    		}
    }
    void dgs(int x,int p){
    	top[x]=p; l[x]=++clk;
    	if(son[x]) dgs(son[x],p);
    	for(int v,i=h[x];i;i=G[i].nt)
    		if(!l[v=G[i].v]) dgs(v,v);
    }
    void insert(int l,int r,int& x,int p,int k){
    	if(!x) x=++tot;
    	if(l==r) { s[x].s=s[x].m=k; return; }
    	if(p<=mid) insert(l,mid,s[x].l,p,k);
    		else insert(mid+1,r,s[x].r,p,k);
    	ps(s[x]);
    }
    void remove(int l,int r,int& x,int p){
    	if(l==r){ x=0; return; }
    	if(p<=mid) remove(l,mid,s[x].l,p);
    		else remove(mid+1,r,s[x].r,p);
    	if(s[x].l || s[x].r) ps(s[x]); else x=0;
    }
    void modify(int l,int r,int x,int p,int k){
    	if(l==r){ s[x].s=s[x].m=k; return; }
    	if(p<=mid) modify(l,mid,s[x].l,p,k);
    		else modify(mid+1,r,s[x].r,p,k);
    	ps(s[x]);
    }
    int queryS(int l,int r,int x,int L,int R){
    	if(!x) return 0;
    	if(L<=l && r<=R) return s[x].s;
    	int ans=0;
    	if(L<=mid) ans+=queryS(l,mid,s[x].l,L,R);
    	if(mid<R) ans+=queryS(mid+1,r,s[x].r,L,R);
    	return ans;
    }
    int gSum(int x,int y){
    	int ans=0,C=c[x];
    	for(;top[x]!=top[y];y=f[top[y]]){
    		if(d[top[x]]>d[top[y]]) swap(x,y);
    		ans+=queryS(1,n,rt[C],l[top[y]],l[y]);
    	}
    	if(d[x]>d[y]) swap(x,y);
    	return ans+queryS(1,n,rt[C],l[x],l[y]);
    }
    int queryM(int l,int r,int x,int L,int R){
    	if(!x) return 0;
    	if(L<=l && r<=R) return s[x].m;
    	int ans=0;
    	if(L<=mid) gmax(ans,queryM(l,mid,s[x].l,L,R));
    	if(mid<R) gmax(ans,queryM(mid+1,r,s[x].r,L,R));
    	return ans;
    }
    int gMax(int x,int y){
    	int ans=0,C=c[x];
    	for(;top[x]!=top[y];y=f[top[y]]){
    		if(d[top[x]]>d[top[y]]) swap(x,y);
    		gmax(ans,queryM(1,n,rt[C],l[top[y]],l[y]));
    	}
    	if(d[x]>d[y]) swap(x,y);
    	return max(ans,queryM(1,n,rt[C],l[x],l[y]));
    }
    int main(){
    	freopen("travel.in","r",stdin);
    	freopen("travel.out","w",stdout); 
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i) scanf("%d%d",w+i,c+i);
    	for(int x,y,i=1;i<n;++i) scanf("%d%d",&x,&y),adj(x,y); 
    	dfs(1,0); dgs(1,1); char o[3];
    	for(int i=1;i<=n;++i) insert(1,n,rt[c[i]],l[i],w[i]);
    	for(int x,y;m--;){
    		scanf("%s%d%d",o,&x,&y);
    		if(*o=='C'){
    			if(o[1]=='C'){
    				remove(1,n,rt[c[x]],l[x]);
    				insert(1,n,rt[y],l[x],w[x]);
    				c[x]=y;
    			} else {
    				modify(1,n,rt[c[x]],l[x],y);
    				w[x]=y;
    			}
    		} else {
    			if(o[1]=='S') printf("%d
    ",gSum(x,y));
    					else printf("%d
    ",gMax(x,y));
    		}
    	}
    }

  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/8312593.html
Copyright © 2011-2022 走看看