zoukankan      html  css  js  c++  java
  • uoj#33. 【UR #2】树上GCD

    http://uoj.ac/problem/33

    长链剖分,每条链用类似分块的方式维护深度%x=y的个数,可以自底向上合并信息。

    #include<bits/stdc++.h>
    typedef long long i64;
    const int N=2e5+7;
    char rb[N*12],*rp=rb;
    int _(){
        int x=0;
        while(*rp<48)++rp;
        while(*rp>47)x=x*10+*rp++-48;
        return x;
    }
    std::vector<int>e[N];
    int n,md[N],top[N],dep[N],dc[N];
    i64 ans[N];
    inline void maxs(int&a,int b){if(a<b)a=b;}
    inline bool cmp_md(int a,int b){return md[a]<md[b];}
    template<class T>
    inline T*$(int L,int R){
        static T mem[N*5],*mp=mem;
        T*r=mp-L;
        mp+=R-L+1;
        return r;
    }
    struct dat{
        int mx,B,*d1,**d2,*d3;
        void ins(int x,int y){
            for(int i=1;i<=B;++i)d2[i][x%i]+=y;
            d1[x]+=y;
        }
        int que(int x,int y){
            if(x<=B)return d2[x][y];
            int s=0;
            if(!y)y=x;
            for(int i=y;i<=mx;i+=x)s+=d1[i];
            return s;
        }
        void init(int n){
            B=sqrt(mx=n);
            d1=$<int>(1,mx);
            d2=$<int*>(1,B);
            for(int i=1;i<=B;++i)d2[i]=$<int>(0,i-1);
        }
        void cal(){
            d3=$<int>(1,mx);
            for(int i=1;i<=mx;++i){
                for(int j=i;j<=mx;j+=i)d3[i]+=d1[j];
            }
        }
        void mg1(dat&w){
            for(int i=1;i<=w.mx;++i){
                d1[i]+=w.d1[i];
                ans[i]+=i64(d3[i])*w.d3[i];
                d3[i]+=w.d3[i];
            }
        }
        void mg2(dat&w,int d){
            for(int i=1;i<=w.mx;++i){
                ans[i]+=i64(w.d3[i])*que(i,d%i);
            }
            for(int i=1;i<=w.mx;++i){
                ins(d+i,w.d1[i]);
            }
        }
    }ds[N];
    void f1(int w){
        ++dc[dep[w]];
        for(int i=0;i<e[w].size();++i){
            int u=e[w][i];
            dep[u]=dep[w]+1;
            f1(u);
            maxs(md[w],md[u]+1);
        }
        std::sort(e[w].begin(),e[w].end(),cmp_md);
    }
    void f2(int w,int tp){
        top[w]=tp;
        if(e[w].empty())ds[tp].init(dep[w]-dep[tp]+1);
        else{
            int sz=e[w].size();
            f2(e[w][sz-1],tp);
            if(sz>1){
                int u;
                for(int i=0;i<sz-1;++i){
                    u=e[w][i];
                    f2(u,u);
                    ds[u].cal();
                    if(i)ds[u].mg1(ds[e[w][i-1]]);
                }
                u=e[w][sz-2];
                ds[tp].mg2(ds[u],dep[u]-dep[tp]);
            }
        }
        ds[tp].ins(dep[w]-dep[tp]+1,1);
    }
    int ps[N/5],pp=0,mu[N];
    bool np[N];
    int main(){
        fread(rb,1,sizeof(rb),stdin);
        n=_();
        mu[1]=1;
        for(int i=2;i<=n;++i){
            if(!np[i])ps[pp++]=i,mu[i]=-1;
            for(int j=0,k;j<pp&&(k=i*ps[j])<=n;++j){
                np[k]=1;
                if(i%ps[j])mu[k]=-mu[i];
                else break;
            }
        }
        for(int i=2;i<=n;++i)e[_()].push_back(i);
        f1(1);
        f2(1,1);
        for(int i=n;i;--i)dc[i]+=dc[i+1];
        for(int i=1;i<n;++i){
            i64 s=0;
            for(int j=i,k=1;j<=n;j+=i,++k)s+=ans[j]*mu[k];
            printf("%lld
    ",s+dc[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7365518.html
Copyright © 2011-2022 走看看