zoukankan      html  css  js  c++  java
  • #树链剖分,线段树#洛谷 1505 [国家集训队]旅游

    题目


    分析

    边权那就将边权变为深度更大的点的点权,
    相反数会影响最值和求和,剩下就是模板了
    注意两次相反数的标记要抵消掉


    代码

    #include <cstdio>
    #include <cctype>
    #define rr register
    using namespace std;
    const int N=200011; struct node{int y,w,next;}e[N<<1];
    int top[N],fat[N],wsum[N<<2],wmin[N<<2],wmax[N<<2],lazy[N<<2];
    int tot,n,K=1,as[N],dfn[N],dep[N],big[N],son[N],A[N],a[N];
    inline signed iut(){
    	rr int ans=0,f=1; rr char c=getchar();
    	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans*f;
    }
    inline void print(int ans){
    	if (ans<0) putchar('-'),ans=-ans;
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline void Swap(int &x,int &y){rr int t=x; x=y; y=t;}
    inline signed min(int a,int b){return a<b?a:b;}
    inline signed max(int a,int b){return a>b?a:b;}
    inline void pup(int k){
        wsum[k]=wsum[k<<1]+wsum[k<<1|1],
    	wmin[k]=min(wmin[k<<1],wmin[k<<1|1]),
    	wmax[k]=max(wmax[k<<1],wmax[k<<1|1]);
    }
    inline void ptag(int k){
        Swap(wmin[k],wmax[k]),wsum[k]=-wsum[k],
    	wmin[k]=-wmin[k],wmax[k]=-wmax[k],lazy[k]^=1;
    }
    inline void pdown(int k){ptag(k<<1),ptag(k<<1|1),lazy[k]=0;}
    inline void build(int k,int l,int r){
    	if (l==r){
    		wmin[k]=wmax[k]=wsum[k]=a[l];
    		return;
    	}
    	rr int mid=(l+r)>>1;
    	build(k<<1,l,mid);
    	build(k<<1|1,mid+1,r);
    	pup(k);
    }
    inline void single(int k,int l,int r,int x,int y){
    	if (l==r) {wmin[k]=wmax[k]=wsum[k]=y,lazy[k]=0; return;}
    	rr int mid=(l+r)>>1; if (lazy[k]) pdown(k);
    	if (x<=mid) single(k<<1,l,mid,x,y);
    	    else single(k<<1|1,mid+1,r,x,y);
    	pup(k);
    }
    inline void update(int k,int l,int r,int x,int y){
    	if (l==x&&r==y) {ptag(k); return;}
    	rr int mid=(l+r)>>1; if (lazy[k]) pdown(k);
    	if (y<=mid) update(k<<1,l,mid,x,y);
    	else if (x>mid) update(k<<1|1,mid+1,r,x,y);
    	else update(k<<1,l,mid,x,mid),update(k<<1|1,mid+1,r,mid+1,y);
    	pup(k);
    }
    inline signed query(int k,int l,int r,int x,int y,int z){
    	if (l==x&&r==y){
    		if (!z) return wmin[k];
    		else if (z==1) return wmax[k];
    		    else return wsum[k];
    	}
    	rr int mid=(l+r)>>1; if (lazy[k]) pdown(k);
    	if (y<=mid) return query(k<<1,l,mid,x,y,z);
    	else if (x>mid) return query(k<<1|1,mid+1,r,x,y,z);
    	else{
    		rr int ans1=query(k<<1,l,mid,x,mid,z);
    		rr int ans2=query(k<<1|1,mid+1,r,mid+1,y,z);
    		if (z==1) return max(ans1,ans2);
    		else if (z==2) return ans1+ans2;
    		    else return min(ans1,ans2);
    	}
    }
    inline void Update(int x,int y){
    	for (;top[x]!=top[y];x=fat[top[x]]){
    		if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
    		update(1,1,n,dfn[top[x]],dfn[x]);
    	}
    	if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
    	if (dfn[x]<dfn[y]) update(1,1,n,dfn[x]+1,dfn[y]);
    }
    inline signed Query(int x,int y,int z){
    	rr int ans=(z==2)?0:((z==1)?-1001:1001);
    	for (;top[x]!=top[y];x=fat[top[x]]){
    		if (dep[top[x]]<dep[top[y]]) x^=y,y^=x,x^=y;
    		rr int tans=query(1,1,n,dfn[top[x]],dfn[x],z);
    		if (z==1) ans=max(ans,tans);
    		else if (z==2) ans+=tans;
    		    else ans=min(ans,tans);
    	}
    	if (dep[x]>dep[y]) x^=y,y^=x,x^=y;
    	if (dfn[x]<dfn[y]){
    	    rr int tans=query(1,1,n,dfn[x]+1,dfn[y],z);
    		if (z==1) ans=max(ans,tans);
    		else if (z==2) ans+=tans;
    		    else ans=min(ans,tans);	    
        }
    	return ans;
    }
    inline void dfs1(int x,int fa){
    	dep[x]=dep[fa]+1,fat[x]=fa,son[x]=1;
    	for (rr int i=as[x],mson=-1;i;i=e[i].next)
    	if (e[i].y!=fa){
    		dfs1(e[i].y,x); A[e[i].y]=e[i].w;
    		son[x]+=son[e[i].y];
    		if (son[e[i].y]>mson) big[x]=e[i].y,mson=son[e[i].y];
    	}
    }
    inline void dfs2(int x,int linp){
    	dfn[x]=++tot,top[x]=linp,a[dfn[x]]=A[x];
    	if (!big[x]) return; dfs2(big[x],linp);
    	for (rr int i=as[x];i;i=e[i].next)
    	    if (e[i].y!=fat[x]&&e[i].y!=big[x])
    	        dfs2(e[i].y,e[i].y);
    }
    signed main(){
    	n=iut();
    	for (rr int i=1;i<n;++i){
    		rr int x=iut()+1,y=iut()+1,w=iut();
    		e[++K]=(node){y,w,as[x]},as[x]=K;
    		e[++K]=(node){x,w,as[y]},as[y]=K;
    	}
    	dfs1(1,0),dfs2(1,1),build(1,1,n);
    	rr char ss[5];
    	for (rr int T=iut();T;--T){
    		scanf("%s",ss);
    		rr int x=iut()+1,y=iut()+1;
            switch (ss[0]){
            	case 'C':{
            		--x; --y;
            		rr int X=e[x<<1].y,Y=e[x<<1|1].y;
            		if (dep[X]<dep[Y]) X^=Y,Y^=X,X^=Y;
            		single(1,1,n,dfn[X],y);
    				break;
    			}
    			case 'N':{
    				Update(x,y);
    				break;
    			}
    			case 'S':{
    				print(Query(x,y,2)),putchar(10);
    				break;
    			}
    			case 'M':{
    				if (ss[1]=='I') print(Query(x,y,0));
    				    else print(Query(x,y,1));
    				putchar(10);
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    [译]6.1. Data Structures Featured in This Chapter 本章涉及到的数据结构
    Linux中进程结构描述符
    How to uninstall GRUB
    [每日一点]msgsnd函数代码跟踪
    开始从代码入手学习内核
    剖析MagicAjax
    Castle实践6-TypedFactory Facility
    移植MSPetShop3到Castle MonoRail -Model与DAL层的移植(AR)
    热血江湖外挂之【热血江湖自补器 Version 0.1】
    对 "闭包closure" 的一些见解
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13695604.html
Copyright © 2011-2022 走看看