zoukankan      html  css  js  c++  java
  • 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);
    		}
    	}
    }
  • 相关阅读:
    SSH出现ls command not found
    SVN打包备份
    【转】Linux安装JDK1.7 prm
    任务
    java多线程
    JAVA开发中151个建议
    Linux Too Many OpenFiles
    【收藏】Linux tail命令
    Linux读取属性配置文件注意事项
    [转]Linux端口查看命令
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14801061.html
Copyright © 2011-2022 走看看