zoukankan      html  css  js  c++  java
  • CF293E Close Vertices 点分治+树状数组

    开始zz写了一个主席树,后来发现写个树状数组就行~

    #include <cstdio>  
    #include <vector>   
    #include <algorithm>    
    #include <bits/stdc++.h> 
    #define N 100005   
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    int length,weight;    
    namespace BIT
    { 
        int C[N];
        int lowbit(int t) 
        {
            return t&(-t); 
        }
        void update(int x,int v) 
        {
            for(;x<N;x+=lowbit(x)) C[x]+=v;
        }
        int query(int x)
        {
            int re=0;
            for(;x>0;x-=lowbit(x)) re+=C[x];
            return re;      
        }
    }; 
    ll answer; 
    struct Node
    {
        int u,d1,d2;  
        Node(int u=0,int d1=0,int d2=0):u(u),d1(d1),d2(d2){}   
    };  
    vector<Node>v;    
    bool cmp(Node a,Node b) 
    {
        return a.d2<b.d2;     
    }
    int n,edges,root,sn; 
    int hd[N],to[N<<1],nex[N<<1],val[N<<1];   
    int size[N],mx[N],vis[N],rt[N]; 
    void add(int u,int v,int c) 
    {
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; 
    } 
    void getroot(int u,int ff)
    {
        size[u]=1,mx[u]=0; 
        for(int i=hd[u];i;i=nex[i]) 
            if(to[i]!=ff&&!vis[to[i]]) 
                getroot(to[i],u),size[u]+=size[to[i]],mx[u]=max(mx[u],size[to[i]]); 
        mx[u]=max(mx[u],sn-size[u]); 
        if(mx[u]<mx[root]) root=u; 
    }   
    // d1<=l d2<=w
    void getdis(int u,int ff,int d1,int d2) 
    {  
        v.push_back(Node(u,d1,d2));  
        for(int i=hd[u];i;i=nex[i]) 
            if(to[i]!=ff&&!vis[to[i]]) 
                getdis(to[i],u,d1+1,d2+val[i]);    
    }
    ll calc(int u,int D1,int D2) 
    {    
        getdis(u,0,D1,D2);      
        sort(v.begin(),v.end(),cmp); 
        ll re=0; 
        int i,j,l=0,r=(int)v.size()-1;   
        for(i=1;i<(int)v.size();++i) BIT::update(v[i].d1+1,1);
        while(l<r) 
        {
            if(v[l].d2+v[r].d2<=weight) 
            {
                re+=(ll)BIT::query(length-v[l].d1+1); 
                ++l,BIT::update(v[l].d1+1,-1); 
            }
            else 
            {
                BIT::update(v[r].d1+1,-1); 
                --r;       
            }
        } 
        v.clear();  
        return re; 
    }
    void solve(int u) 
    { 
        vis[u]=1; 
        answer+=calc(u,0,0);     
        for(int i=hd[u];i;i=nex[i]) if(!vis[to[i]]) answer-=calc(to[i],1,val[i]);            
        for(int i=hd[u];i;i=nex[i]) 
            if(!vis[to[i]]) 
                sn=size[to[i]],root=0,getroot(to[i],u),solve(root);    
    }
    int main() 
    {
        int i,j; 
        // setIO("input");  
        scanf("%d%d%d",&n,&length,&weight);  
        for(i=1;i<n;++i) 
        {
            int a=i+1,b,c; 
            scanf("%d%d",&b,&c),add(a,b,c),add(b,a,c);       
        }    
        mx[root=0]=sn=n,getroot(1,0),solve(root);   
        printf("%lld
    ",answer);    
        return 0;    
    }
    

      

  • 相关阅读:
    C# 中文件路径的操作
    字符串模式匹配KMP算法
    SLG游戏关卡设计
    android 源码包结构分析
    NIO的理解
    显示单位
    多线程时控制并发数据库操作的思路
    使用异常机制的建议
    合理的使用索引。《Map的使用》
    android源码的下载方法Windows
  • 原文地址:https://www.cnblogs.com/guangheli/p/11478963.html
Copyright © 2011-2022 走看看