zoukankan      html  css  js  c++  java
  • Topcoder--SRM698-Div2 : SubtreeSum

    题意 : 给你一棵树,每个节点有点权,树上的每一个联通子图的价值为联通子图中所有节点点权的or和。求这棵树所有联通子图价值和。

    显然可以去考虑增量计算,假如我们有了一棵树,在这棵树上加入一个节点会对答案有多少贡献呢?

    考虑对于多出来的联通子图,一定且必须包含有新加入的这个节点才是一个没被计算过的联通子图

    把加入的这个节点点权拆成二进制来看,对于每一个二进制位为1的位,每个包含该节点的联通子图都有贡献

    对于每个二进制为0的位,只有在包含另一个这个位为1的节点时才有贡献

    所以可以设计出一个n^2log的算法

    代码 : 

    class SubtreeSum {
        public:
        #define MOD 1000000007
        int head[55],cnt,n;long long w[55];
        bool open[55];long long ret;long long k;
        struct Edge{
            int to,next;
        }e[205];
        inline void insert(int a,int b) {
            e[++cnt].next=head[a];head[a]=cnt;e[cnt].to=b;
            e[++cnt].next=head[b];head[b]=cnt;e[cnt].to=a;
        }
        
        void init() {
            memset(head,0,sizeof(head));cnt=0;
            ret=0;
        }
        
        bool vis[55];
        
        int Cdfs(int v) {
            long long ret=1;vis[v]=1;
            for(int i=head[v];i;i=e[i].next) if(!vis[e[i].to]) 
                ret=ret*(Cdfs(e[i].to)+1)%MOD;
            return ret;
        }
        int comp(int bit,int v) {
            memset(vis,0,sizeof(vis));
            for(int i=0;i<=n;i++) 
                if(!open[i]||w[i]>>bit&1) vis[i]=1;
            vis[v]=0;
            return Cdfs(v);
        }
        void dfs(int v) {
            for(int j=0;j<30;j++) 
                if(w[v]>>j&1) {
                    k=comp(31,v);k*=1<<j;
                    k%=MOD;ret=(ret+k)%MOD;
                }
                else {
                    k=comp(31,v)-comp(j,v);k*=1<<j;
                    k%=MOD;ret=(ret+k)%MOD;
                }
            open[v]=1;
            for(int i=head[v];i;i=e[i].next) 
                if(!open[e[i].to]) dfs(e[i].to);
        }
        
        int getSum(vector<int> p, vector<int> x) {
            init();
            n=p.size();
            for(int i=0;i<n;i++) insert(p[i],i+1);
            for(int i=0;i<=n;i++) w[i]=x[i];
            dfs(0);
            return ret;
        }
        
    };
  • 相关阅读:
    WebApi 接口参数不再困惑:传参详解
    dataType和contentType的区别
    WaitHandles 的数目必须少于或等于 64 个--任意线程信号量监视
    跨线程调用DataGridView控件
    (转)调整.NET控件WebBrowser的默认浏览器内核版本
    Winform中checklistbox控件的常用方法
    csuoj 残缺的棋盘
    csuoj 你经历过绝望吗?两次! bfs + 优先队列
    csuoj barricade
    csuoj 集训队分组
  • 原文地址:https://www.cnblogs.com/ihopenot/p/6032495.html
Copyright © 2011-2022 走看看