• hdu5314 Happy King


       树分治。

    代码

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    #define N 300010
    using namespace std;
    int dp,pre[N],p[N],tt[N],cnt,q[N];
    LL c[N],ans; 
    int n,i,a,b,w[N],vis[N],s[N],tmp,d,tot1,tot2,v[N];
    struct g{
        int a,b;
    }A[N],B[N];
    bool cmp(g x,g y)
    {
        return x.b<y.b;
    }
    void link(int x,int y)
    {
        dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void cc(int x,int w)
    {
        while (x<=n)
        {
            c[x]+=w;
            x=x+lowbit(x);
        }
    }
    LL getsum(int x)
    {
        LL ans=0;
        while (x>0)
        {
            ans=ans+c[x];
            x=x-lowbit(x);
        }
        return ans;
    }
    void dfs(int x,int fa,int Min,int Max)
    {
        int i;
        Min=min(Min,w[x]);
        Max=max(Max,w[x]);
        if (Max-Min<=d)
        {
        tot1++;A[tot1].a=Min;A[tot1].b=Max;
        tot2++;B[tot2]=A[tot1];
    	}
    	else
    	return;
    	i=p[x];
        while (i)
        {
            if ((!vis[tt[i]])&&(tt[i]!=fa))
                dfs(tt[i],x,Min,Max);
            i=pre[i];
        }
    }
    void getroot(int x,int fa,int sum)
    {
        int i,flag=0;
        i=p[x];s[x]=1;
        while (i)
        {
            if ((!vis[tt[i]])&&(tt[i]!=fa))
            {
                getroot(tt[i],x,sum);
                s[x]+=s[tt[i]];
                if (s[tt[i]]>sum/2) flag=1;
            }
            i=pre[i];
        }
        if (sum-s[x]>sum/2) flag=1;
        if (!flag) tmp=x;
    }
    int ef(int x)
    {
        int l,r,m;
        l=1;r=n;
        while (l<=r)
        {
            m=(l+r)>>1;
            if (v[m]>x) 
            r=m-1;
            else 
            l=m+1;
        }
        return r;
    }
    void work(int x,int sum)
    {
        int root,i,ta,tb;
        getroot(x,0,sum);
        root=tmp;
        i=p[root];
        vis[root]=1;
        while (i)
        {
            if (!vis[tt[i]])
            {
                if (s[tt[i]]>s[root])
                work(tt[i],sum-s[root]);
                else
                work(tt[i],s[tt[i]]);
            }
            i=pre[i];
        }
        
        tot1=1;
        A[tot1].a=w[root];
    	A[tot1].b=w[root];
        i=p[root];
        while (i)
        {
            if (!vis[tt[i]])
            {
                tot2=0;
                dfs(tt[i],0,w[root],w[root]);
                sort(B+1,B+1+tot2,cmp);
                cnt=0;
                for (int j=1;j<=tot2;j++)
                {
                    ta=ef(B[j].b);
                    tb=ef(B[j].b-d-1);
                    ans=ans-(getsum(ta)-getsum(tb));
                    ta=ef(B[j].a);cnt++;q[cnt]=ta;
                    cc(ta,1);
                }
                
                for (int j=1;j<=cnt;j++)
                cc(q[j],-1);
            }
            i=pre[i];
        }
        sort(A+1,A+1+tot1,cmp);
        cnt=0;
        for (int j=1;j<=tot1;j++)
        {
            ta=ef(A[j].b);
            tb=ef(A[j].b-d-1);
            ans=ans+(getsum(ta)-getsum(tb));
            ta=ef(A[j].a);cnt++;q[cnt]=ta;
            cc(ta,1);
        }
        for (int j=1;j<=cnt;j++)
        cc(q[j],-1);
        vis[root]=0; 
    }
    int main()
    {
        int test;
        scanf("%d",&test);
        while (test)
        {
        test--;
        dp=0;
    	memset(p,0,sizeof(p));
        scanf("%d%d",&n,&d);
        for (i=1;i<=n;i++)
        {
            scanf("%d",&w[i]);
            v[i]=w[i];
        }
        sort(v+1,v+1+n);
        for (i=1;i<=n-1;i++)
        {
            scanf("%d%d",&a,&b);
            link(a,b);
            link(b,a);
        }
        ans=0;
        work(1,n);
        printf("%I64d
    ",ans*2);
        }
    }
    

      

  • 相关阅读:
    MD5双重加密设计
    ComBox(自定义封装)LimitToList属性和做到移走光标不是下拉项清空输入
    强制下线功能
    广播
    动态添加碎片
    RecyclerView
    Listview的运行效率
    Listview
    通知栏
    补间动画
  • 原文地址:https://www.cnblogs.com/fzmh/p/4700791.html
Copyright © 2020-2023  润新知