• [USACO19DEC]Bessie's Snow Cow


    题目

    显然这个子树操作是假的,我们dfs序一下就变成区间了

    不难想到我们可以对于每一种颜色维护一个set,表示序列里哪些位置被涂上了这种颜色;对于修改操作,我们去对应颜色的set里处理一下和当前区间有交的区间,用线段树维护一下区间修改即可

    至于复杂度,由于一段区间最多会被删除一次,所以是(O((n+q)log n))

    代码

    include<bits/stdc++.h>
    #define re register
    #define LL long long
    #define mp std::make_pair
    inline int read() {
    	char c=getchar();int x=0;while(c<'0'||c>'9')c=getchar();
    	while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    const int maxn=1e5+5;
    typedef std::pair<int,int> pii;
    struct E{int v,nxt;}e[maxn<<1];pii st[maxn];
    int n,m,head[maxn],num,sum[maxn],dfn[maxn],top,__;
    inline void add_(int x,int y){e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
    struct Segment_Tree {
    	int l[maxn<<2],r[maxn<<2],tag[maxn<<2];LL d[maxn<<2];
    	inline void pushr(int i,int v) {d[i]+=1ll*v*(r[i]-l[i]+1);tag[i]+=v;}
    	inline void pushdown(int i) {
    		if(!tag[i])return;pushr(i<<1,tag[i]),pushr(i<<1|1,tag[i]);tag[i]=0;
    	}
    	inline void pushup(int i) {d[i]=d[i<<1]+d[i<<1|1];}
    	void build(int x,int y,int i) {
    		l[i]=x,r[i]=y;if(x==y)return;
    		int mid=x+y>>1;build(x,mid,i<<1),build(mid+1,y,i<<1|1);
    	}
    	void add(int x,int y,int v,int i) {
    		if(x<=l[i]&&y>=r[i]) {pushr(i,v);return;}
    		int mid=l[i]+r[i]>>1;pushdown(i);
    		if(x<=mid)add(x,y,v,i<<1);if(y>mid)add(x,y,v,i<<1|1);pushup(i);
    	}
    	LL query(int x,int y,int i) {
    		if(x<=l[i]&&y>=r[i]) return d[i];
    		int mid=l[i]+r[i]>>1;pushdown(i);
    		return (x<=mid?query(x,y,i<<1):0)+(y>mid?query(x,y,i<<1|1):0);
    	}
    }T;
    struct Set {
    	std::set<pii> s;
    	#define fl first
    	#define fr second
    	std::set<pii>::iterator it;
    	inline void ins(int l,int r) {
    		top=0;it=s.lower_bound(mp(l,0));
    		if(it!=s.begin()) --it; 
    		for(;it!=s.end();++it) {
    			pii k=(*it);if(k.fr<l) continue;
    			if(k.fl>r) break;
    			st[++top]=k;T.add(k.fl,k.fr,-1,1);
    		}
    		if(!top) {
    			s.insert(mp(l,r));T.add(l,r,1,1);return;
    		}
    		for(re int i=1;i<=top;i++) s.erase(st[i]);
    		int L=l,R=r;if(st[1].fl<L) L=st[1].fl;if(st[top].fr>R) R=st[top].fr;
    		s.insert(mp(L,R)),T.add(L,R,1,1);
    	}
    }seg[maxn];
    void dfs(int x) {
    	dfn[x]=++__;sum[x]=1;
    	for(re int i=head[x];i;i=e[i].nxt)
    		if(!dfn[e[i].v]) dfs(e[i].v),sum[x]+=sum[e[i].v];
    }
    int main() {
    	n=read(),m=read();
    	for(re int x,y,i=1;i<n;i++) x=read(),y=read(),add_(x,y),add_(y,x);
    	dfs(1);T.build(1,n,1);int op,x,c;
    	while(m--) {
    		op=read(),x=read();
    		if(op==1) c=read(),seg[c].ins(dfn[x],dfn[x]+sum[x]-1);
    		if(op==2) printf("%lld
    ",T.query(dfn[x],dfn[x]+sum[x]-1,1));
    	}return 0;
    }
    
  • 相关阅读:
    Array
    自底向上的单元测试&&程序设计思想
    如何从 100 亿 URL 中找出相同的 URL?
    个人博客开发之数据库设计
    SpringBoot 优雅整合Swagger Api 自动生成文档
    SpringBoot Validation参数校验 详解自定义注解规则和分组校验
    SpringBoot Validation优雅的全局参数校验
    Spring Boot 无侵入式 实现RESTful API接口统一JSON格式返回
    SpringBoot优雅的全局异常处理
    SpringBoot2.4.x整合Mybatis-Plus3.4.x(详细教程)
  • 原文地址:https://www.cnblogs.com/asuldb/p/12112401.html
Copyright © 2020-2023  润新知