zoukankan      html  css  js  c++  java
  • Gym102538A Airplane Cliques

    Link
    我们用(T)来表示题目给出的树,用(S)来表示枚举的点集。
    不难发现(G=T^x)是一个弦图。((T^x)指将(T)中距离不超过(x)的点两两连边得到的图)
    然后我们任意固定一个点为根,然后将所有点按深度降序排序。事实上这个序列恰好是(G)的一个完美消除序列。
    (a_u)表示在完美消除序列中在(u)后面的且和(u)相邻的点的个数,这可以通过点分治等途径求出。
    固定(|S|=k),然后枚举(S)中在完美消除序列中最靠前的点(u),那么选择其它(k-1)个点的方案数就是({a_uchoose k-1})
    (f_i)(|S|=i+1)的个数,那么有(f_i=sumlimits_{j=1}^n{a_jchoose i})
    (t_x=sumlimits_{i=1}^n[a_u=x]),那么(f_i=sumlimits_{j=i}^{n-1}t_j{jchoose i})
    利用NTT即可求出(f)

    #include<cctype>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<numeric>
    #include<algorithm>
    const int N=1<<20|1,P=998244353;
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
    void dec(int&a,int b){a-=b,a+=a>>31&P;}
    int mul(int a,int b){return 1ll*a*b%P;}
    int pow(int a,int k){int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
    int n,x,lim,cnt[N],dep[N],pre[N],id[N],fac[N],ifac[N],w[N],rev[N],f[N],g[N];std::vector<int>e[N];
    namespace Divide_and_Conquer
    {
        int root,mn,m1,m2,vis[N],size[N],s1[N],s2[N];
        void dfs(int u){size[u]=vis[u]=1;for(int v:e[u])if(!vis[v])dfs(v),size[u]+=size[v];vis[u]=0;}
        void find(int u,int s){int mx=0;vis[u]=1;for(int v:e[u])if(!vis[v])find(v,s),mx=std::max(mx,size[v]);if(vis[u]=0,(mx=std::max(mx,s-size[u]))<mn)root=u,mn=mx;}
        int get(int u,int d,int*s){int mx=d;if(vis[u]=1,u<=n)++s[d];for(int v:e[u])if(!vis[v])mx=std::max(mx,get(v,d+1,s));return vis[u]=0,mx;}
        void calc(int u,int d){if(d>x) return;cnt[u]+=s1[std::min(x-d,m1)]-s2[std::min(x-d,m2)],vis[u]=1;for(int v:e[u])if(!vis[v])calc(v,d+1);vis[u]=0;}
        void divide(int u)
        {
    	mn=1e9,dfs(u),find(u,size[u]),u=root,m1=get(u,0,s1),std::partial_sum(s1,s1+m1+1,s1),cnt[u]+=s1[std::min(m1,x)],vis[u]=1;
    	for(int v:e[u]) if(!vis[v]) m2=get(v,1,s2),std::partial_sum(s2,s2+m2+1,s2),calc(v,1),memset(s2,0,(m2+1)<<2);
    	memset(s1,0,(m1+1)<<2);
    	for(int v:e[u]) if(!vis[v]) divide(v);
        }
    }
    void dfs(int u,int fa)
    {
        static int stk[N],top;
        dep[u]=dep[fa]+1,stk[++top]=u,pre[u]=stk[std::max(1,top-x)];
        for(int v:e[u]) if(v^fa) dfs(v,u);
        --top;
    }
    void init(int n)
    {
        static int p=(lim=1<<(33-__builtin_clz(n)))/2,g=pow(3,(P-1)/lim);
        w[p]=1,fac[0]=1;
        for(int i=1;i<lim;++i) rev[i]=(rev[i>>1]>>1)|(i&1? p:0);
        for(int i=p+1;i<lim;++i) w[i]=mul(w[i-1],g);
        for(int i=p-1;i;--i) w[i]=w[i<<1];
        for(int i=1;i<=n;++i) fac[i]=mul(fac[i-1],i);
        ifac[n]=pow(fac[n],P-2);
        for(int i=n;i;--i) ifac[i-1]=mul(ifac[i],i);
    }
    void NTT(int*a,int f)
    {
        if(!~f) std::reverse(a+1,a+lim);
        for(int i=1;i<lim;++i) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
        for(int i=1;i<lim;i<<=1) for(int j=0,d=i<<1;j<lim;j+=d) for(int k=0,x;k<i;++k) x=mul(a[i+j+k],w[i+k]),dec(a[i+j+k]=a[j+k],x),inc(a[j+k],x);
        if(!~f) for(int i=0,x=P-(P-1)/lim;i<lim;++i) a[i]=mul(a[i],x);
    }
    int main()
    {
        n=read(),x=read(),init(n-1),memcpy(g,ifac,n<<2),std::reverse(g,g+n);
        for(int i=1,u,v;i<n;++i) u=read(),v=read(),e[u].push_back(n+i),e[v].push_back(n+i),e[n+i].push_back(u),e[n+i].push_back(v);
        Divide_and_Conquer::divide(1),dfs(1,0),std::iota(id+1,id+n+1,1),std::sort(id+1,id+n+1,[](int i,int j){return dep[i]>dep[j];});
        for(int i=1;i<=n;++i) ++f[--cnt[pre[i]]];
        for(int i=0;i<n;++i) f[i]=mul(f[i],fac[i]);
        NTT(f,1),NTT(g,1);
        for(int i=0;i<lim;++i) f[i]=mul(f[i],g[i]);
        NTT(f,-1);
        for(int i=0;i<n;++i) printf("%d ",mul(ifac[i],f[i+n-1]));
    }
    
  • 相关阅读:
    OpenCV下载
    ffmpeg.转换示例_处理流程
    调试.pdb&源码
    OpenCV.图片透明
    ffmpeg.用vs2017编译(20200102)
    ffmpeg.视频转码
    ffmpeg.串流_资料(包含一些vlc)
    Qt563x86vs2015.编译错误(TypeError: Property 'asciify' of object Core::Internal::UtilsJsExtension(0x????????) is not a function)
    前端性能优化规则
    前端性能优化 —— reflow(回流)和repaint(重绘)
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12687717.html
Copyright © 2011-2022 走看看