• 620E New Year Tree(线段树维护状压)


    #include<bits/stdc++.h>
    using namespace std;
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    	return x*f;
    }
    
    const int maxn=4e5+100;
    
    //线段树+状压
    //线段树的权值表示区间颜色的出现次数
    typedef long long ll;
    vector<int> g[maxn]; 
    ll c[maxn<<2],lz[maxn<<2];
    int a[maxn];
    int w[maxn];
    int n,q;
    int dfn[maxn],tot,sz[maxn];
    void dfs (int x,int pre) {
    	dfn[x]=++tot;
    	w[tot]=a[x];
    	sz[x]=1;
    	for (int y:g[x]) if (y!=pre) dfs(y,x),sz[x]+=sz[y];
    }
    void pushup (int i) {
    	c[i]=(c[i<<1]|c[i<<1|1]);
    }
    void pushdown (int i) {
    	if (lz[i]) {
    		c[i<<1]=lz[i];
    		lz[i<<1]=lz[i];
    		c[i<<1|1]=lz[i];
    		lz[i<<1|1]=lz[i];
    		lz[i]=0;
    	}
    }
    void build (int i,int l,int r)  {
    	if (l==r) {
    		c[i]=(1ll<<(w[l]-1));
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(i<<1,l,mid);
    	build(i<<1|1,mid+1,r);
    	pushup(i);
    }
    void up (int i,int l,int r,int L,int R,int x) {
    	if (l>=L&&r<=R) {
    		c[i]=(1ll<<(x-1));
    		lz[i]=(1ll<<(x-1));
    		return;
    	}
    	pushdown(i);
    	int mid=(l+r)>>1;
    	if (L<=mid) up(i<<1,l,mid,L,R,x);
    	if (R>mid) up(i<<1|1,mid+1,r,L,R,x);
    	pushup(i);
    }
    long long query (int i,int l,int r,int L,int R) {
    	if (l>=L&&r<=R) return c[i];
    	pushdown(i);
    	int mid=(l+r)>>1;
    	long long ans=0;
    	if (L<=mid) ans|=(query(i<<1,l,mid,L,R));
    	if (R>mid) ans|=(query(i<<1|1,mid+1,r,L,R));
    	return ans;
    }
    int main () {
    	n=read();q=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<n;i++) {
    		int x=read();
    		int y=read();
    		g[x].push_back(y);
    		g[y].push_back(x);
    	}
    	dfs(1,0);
    	build(1,1,n);
    	while (q--) {
    		int op=read();
    		if (op==1) {
    			int x=read();
    			int y=read();
    			up(1,1,n,dfn[x],dfn[x]+sz[x]-1,y);
    		}
    		else {
    			int x=read();
    			long long ans=query(1,1,n,dfn[x],dfn[x]+sz[x]-1);
    			int cnt=0;
    			for (int i=1;i<=60;i++) if (ans&(1ll<<(i-1))) cnt++;
    			printf("%d
    ",cnt);
    		}
    	}
    }
  • 相关阅读:
    Leetcode-Daily: Jewels and Stones
    Spark专题(二):Hadoop Shuffle VS Spark Shuffle
    Spark专题(一):Spark工作原理图
    我司建立图书借阅的一点思考
    机器学习的分类方法——逻辑回归
    机器学习的分类算法——集成学习
    浅谈对离散型随机变量期望的理解
    sklearn学习:make_multilabel_classification——多标签数据集方法
    外星人在阴间修仙
    RabbitMQ
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14801061.html
Copyright © 2020-2023  润新知