• 洛谷 [P2486] 染色


    树剖+线段树维护连续相同区间个数

    注意什么时候长度要减一

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define ll long long
    using namespace std;
    const int MAXN=100005;
    int top[MAXN],head[MAXN],nume,n,m,dep[MAXN],fa[MAXN],son[MAXN],siz[MAXN],id[MAXN],wei[MAXN],wein[MAXN],ind;
    struct edge{
    	int to,nxt;
    }e[MAXN<<1];
    int init(){
    	int rv=0,fh=1;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		if(c=='-') fh=-1;
    		c=getchar();
    	}
    	while(c>='0'&&c<='9'){
    		rv=(rv<<1)+(rv<<3)+c-'0';
    		c=getchar();
    	}
    	return fh*rv;
    }
    void adde(int from,int to){
    	e[++nume].to=to;
    	e[nume].nxt=head[from];
    	head[from]=nume;
    }
    void dfs1(int u,int rt){
    	dep[u]=dep[rt]+1;
    	fa[u]=rt;
    	siz[u]=1;
    	int ma=0;
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==rt) continue;
    		dfs1(v,u);
    		siz[u]+=siz[v];
    		if(siz[v]>ma){
    			ma=siz[v];
    			son[u]=v;
    		}
    	}
    }
    void dfs2(int u,int topf){
    	top[u]=topf;
    	id[u]=++ind;
    	wein[ind]=wei[u];
    	if(!son[u]) return;
    	dfs2(son[u],topf);
    	for(int i=head[u];i;i=e[i].nxt){
    		int v=e[i].to;
    		if(v==fa[u]||v==son[u]) continue;
    		dfs2(v,v);
    	}
    }
    struct SGT{
    	int sum[MAXN<<2],tag[MAXN<<2],lc[MAXN<<2],rc[MAXN<<2];
    	void PushUp(int rt){
    		sum[rt]=sum[rt<<1]+sum[rt<<1|1]-(rc[rt<<1]==lc[rt<<1|1]);
    		lc[rt]=lc[rt<<1];rc[rt]=rc[rt<<1|1];
    	}
    	void build(int l,int r,int rt){
    		if(l==r){
    			sum[rt]=1;
    			lc[rt]=rc[rt]=wein[l];
    			return ;
    		}
    		int mid=(l+r)>>1;
    		build(lson);
    		build(rson);
    		PushUp(rt);
    	}
    	void PushDown(int rt){
    		if(tag[rt]){
    			tag[rt<<1]=tag[rt<<1|1]=tag[rt];
    			sum[rt<<1]=sum[rt<<1|1]=1;
    			lc[rt<<1]=rc[rt<<1]=lc[rt<<1|1]=rc[rt<<1|1]=tag[rt];
    			tag[rt]=0;
    		}
    	}
    	void Update(int L,int R,int add,int l,int r,int rt){
    		if(L<=l&&r<=R){
    			sum[rt]=1;
    			lc[rt]=rc[rt]=add;
    			tag[rt]=add;
    			return;
    		}
    		PushDown(rt);
    		int mid=(l+r)>>1;
    		if(L<=mid) Update(L,R,add,lson);
    		if(mid<R) Update(L,R,add,rson);
    		PushUp(rt);
    	}
    	int Query(int L,int R,int l,int r,int rt){
    		if(L<=l&&r<=R){
    			return sum[rt];
    		}
    		PushDown(rt);
    		int mid=(l+r)>>1;
    		int ans=0,f=0;
    		if(L<=mid) ans+=Query(L,R,lson),f++;
    		if(mid<R) ans+=Query(L,R,rson),f++;
    		if(f==2){
    			ans-=(rc[rt<<1]==lc[rt<<1|1]);
    		}
    		PushUp(rt);
    		return ans;
    	}
    	int find(int loc,int l,int r,int rt){
    		if(l==r){
    			return rc[rt];
    		}
    		PushDown(rt);
    		int mid=(l+r)>>1;
    		int ans=0;
    		if(loc<=mid) ans=find(loc,lson);
    		else ans=find(loc,rson);
    		PushUp(rt);
    		return ans;
    	}
    }sgt;
    void UpdateRange(int u,int v,int add){
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		sgt.Update(id[top[u]],id[u],add,1,n,1);
    		u=fa[top[u]];
    	}
    	if(dep[u]>dep[v]) swap(u,v);
    	sgt.Update(id[u],id[v],add,1,n,1);
    }
    int QueryRange(int u,int v){
    	int ans=0;
    	while(top[u]!=top[v]){
    		if(dep[top[u]]<dep[top[v]]) swap(u,v);
    		ans+=sgt.Query(id[top[u]],id[u],1,n,1);
    		ans-=(sgt.find(id[fa[top[u]]],1,n,1)==sgt.find(id[top[u]],1,n,1));
    		u=fa[top[u]];
    	}
    	if(dep[u]>dep[v]) swap(u,v);
    	ans+=sgt.Query(id[u],id[v],1,n,1);
    	return ans;
    }
    int main(){
    	n=init();m=init();
    	for(int i=1;i<=n;i++) wei[i]=init();
    	for(int i=1;i<n;i++){
    		int u=init(),v=init();
    		adde(u,v);adde(v,u);
    	}
    	dep[1]=1;
    	dfs1(1,0);
    	dfs2(1,1);
    	sgt.build(1,n,1);
    	char s[10];
    	/*for(int i=1;i<=n;i++) printf("%d ",wein[id[i]]);
    	cout<<endl;
    	for(int i=1;i<=n;i++) printf("%d ",sgt.find(id[i],1,n,1));
    	cout<<endl;*/
    	for(int i=1;i<=m;i++){
    		scanf("%s",s);
    		if(s[0]=='C'){
    			int a=init(),b=init(),t=init();
    			UpdateRange(a,b,t);
    			/*for(int i=1;i<=n;i++) printf("%d ",sgt.find(id[i],1,n,1));
    			cout<<endl;*/
    		}else {
    			int a=init(),b=init();
    			printf("%d
    ",QueryRange(a,b));
    		}
    	}
    	for(int i=1;i<=n;i++) ;
    	return 0;
    }
    
  • 相关阅读:
    支持高速局域网文件传输的企业云盘(速度可达20M)
    高版本Sqlserver数据库还原到低版本数据库的实现方式
    sqlserver没有采用默认实例时 通过ip进行链接
    AM8互联设置方法
    蛮好用的Gungho重点工作督查督办跟踪管理系统
    AM8后台历史数据手工清理方法
    AM8不能下任何载附件及所有聊天记录无法登记
    【OI】时间复杂度
    【OI】矩阵快速幂
    【Ubuntu】奇怪的无法启动
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8410431.html
Copyright © 2020-2023  润新知