zoukankan      html  css  js  c++  java
  • HDU5322 Hope

     
    给出一个排列,每个点向它右面离它最近的且比它大的点连无向边,每个连通块的价值为这个连通块大小的平方,每个排列的价值为所有连通块价值之积。求n个数的所有排列的价值之和。 
     

    动态规划 花式递推/NTT加速

    考虑到放完前i个数再放i+1,不管i+1放在哪里,i+1之前的数形成了一个连通块,且对之后的没有影响。

    设f[i]表示一个大小为i的连通块,枚举其中最大的那个数的位置在第j个,得到方程:

       $ f[i]=sum_{j=1}^{i} f[i-j] * j^2 * C(i-1,j-1)*(j-1)! $

           $  f[i]=(i-1)! *sum_{j=1}^{i} j^2 * f[i-j] / (i-j)! $

    最大的数在第j个位置时,j和它前面的所有数构成一个连通块,方案有$ C(i-1,j-1)*(j-1)! $种,贡献为j^2,j后面的连通块贡献为f[i-1]

    此时复杂度为$O(n^2)$

    接下来可以用数学方法花式递推,或者用分治NTT加速运算

    (公式编辑器好像炸了……)

    数学:

    设k=i-j,上面的sum部分可以拆成三部分递推式

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #define LL long long
     8 using namespace std;
     9 const int mod=998244353;
    10 const int mxn=100005;
    11 LL dp[mxn],f1,f2,f3;
    12 LL inv[mxn],fac[mxn];
    13 void init(){
    14     inv[0]=inv[1]=1;
    15     fac[0]=fac[1]=1;
    16     for(int i=2;i<mxn;i++){
    17         fac[i]=fac[i-1]*i%mod;
    18         inv[i]=((-mod/i)*inv[mod%i]%mod+mod)%mod;
    19     }
    20     for(int i=2;i<mxn;i++)
    21         inv[i]=(inv[i-1]*inv[i])%mod;
    22     //
    23     dp[1]=1;
    24     f1=2;f2=1;f3=1;
    25     for(LL i=2;i<mxn;i++){
    26         dp[i]=fac[i-1]*( (i*i%mod*f1%mod+f2-(i*f3%mod*2%mod))%mod+mod)%mod;
    27         f1=(f1+dp[i]*inv[i]%mod)%mod;
    28         f2=(f2+(i*i%mod*(dp[i]*inv[i]%mod))%mod)%mod;
    29         f3=(f3+i*dp[i]%mod*inv[i]%mod)%mod;
    30     }
    31     return;
    32 }
    33 int main(){
    34     int i,j,x;
    35     init();
    36     while(scanf("%d",&x)!=EOF){
    37         printf("%lld
    ",dp[x]);
    38     }
    39     return 0;
    40 }

    很优美对吧?

    但这是一道NTT的练习题呀

    不用NTT的话就没有意义!

    分治NTT:

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #define LL long long
     8 using namespace std;
     9 const int mod=998244353;
    10 const int G=3;
    11 const int mxn=100010;
    12 int read(){
    13     int x=0,f=1;char ch=getchar();
    14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    16     return x*f;
    17 }
    18 LL inv[mxn],fac[mxn];
    19 void init(){
    20     inv[0]=inv[1]=1;
    21     fac[0]=fac[1]=1;
    22     for(int i=2;i<mxn;i++){
    23         fac[i]=fac[i-1]*i%mod;
    24         inv[i]=((-mod/i)*inv[mod%i]%mod+mod)%mod;
    25     }
    26     for(int i=2;i<mxn;i++)inv[i]=inv[i-1]*inv[i]%mod;
    27     return;
    28 }
    29 LL ksm(LL a,LL k){
    30     LL res=1;
    31     while(k){
    32         if(k&1)res=res*a%mod;
    33         a=a*a%mod;
    34         k>>=1;
    35     }
    36     return res;
    37 }
    38 int N,len,rev[mxn<<1];
    39 LL a[mxn<<1],b[mxn<<1];
    40 LL f[mxn];
    41 void NTT(LL *a,int flag){
    42     for(int i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
    43     for(int i=1;i<N;i<<=1){
    44         int p=i<<1;
    45         LL gn=ksm(G,(flag==1)?(mod-1)/p:(mod-1)-(mod-1)/p);
    46         for(int j=0;j<N;j+=p){
    47             LL g=1;
    48             for(int k=0;k<i;k++,g=g*gn%mod){
    49                 LL x=a[j+k],y=g*a[j+k+i]%mod;
    50                 a[j+k]=(x+y)%mod;
    51                 a[j+k+i]=(x-y+mod)%mod;
    52             }
    53         }
    54     }
    55     if(flag==-1){
    56         LL INV=ksm(N,mod-2);
    57         for(int i=0;i<N;i++)a[i]=a[i]*INV%mod;
    58     }
    59     return;
    60 }
    61 void solve(int l,int r){
    62     if(l==r){
    63         f[l]=(f[l]+(LL)l*l%mod)*fac[l-1]%mod;
    64         return;
    65     }
    66     int i,j,mid=(l+r)>>1;
    67     solve(l,mid);
    68     int m=(mid-l+1)<<1;
    69     for(N=1,len=0;N<=m;N<<=1)len++;
    70     for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
    71     for(i=0;i<N;i++)a[i]=b[i]=0;
    72     for(i=l;i<=mid;i++)
    73         a[i-l]=f[i]*inv[i]%mod; 
    74     for(i=l;i<=r;i++)
    75         b[i-l]=(LL)(i-l)*(i-l)%mod;
    76     NTT(a,1);NTT(b,1);
    77     for(i=0;i<N;i++)a[i]=a[i]*b[i]%mod;
    78     NTT(a,-1);
    79     for(i=mid+1;i<=r;i++){
    80         (f[i]+=a[i-l])%=mod;
    81     }
    82     solve(mid+1,r);
    83     return;
    84 }
    85 int main(){
    86     int i,j,x;
    87     init();
    88     f[0]=1;
    89     solve(0,100000);
    90     while(scanf("%d",&x)!=EOF){
    91         printf("%lld
    ",f[x]);
    92     }
    93     return 0;
    94 }

     

    Hope is a good thing, which can help you conquer obstacles in your life, just keep fighting, and solve the problem below. 



    In mathematics, the notion of permutation relates to the act of arranging all the members of a set into some sequence or order, or if the set is already ordered, rearranging (reordering) its elements, a process called permuting. These differ from combinations, which are selections of some members of a set where order is disregarded. For example, written as tuples, there are six permutations of the set {1,2,3}, namely: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), and (3,2,1). These are all the possible orderings of this three element set. As another example, an anagram of a word, all of whose letters are different, is a permutation of its letters. In this example, the letters are already ordered in the original word and the anagram is a reordering of the letters. 
    There is a permutation A1,A2,...AnA1,A2,...An, now we define its value as below: 
    For each AiAi, if there exists a minimum jj satisfies j>ij>i and Aj>AiAj>Ai , then connect an edge between AiAi and AjAj , so after we connect all the edges, there is a graph G, calculate the product of the number of nodes in each component as an integer P. The permutation value is P * P.Now, Mr. Zstu wants to know the sum of all the permutation value of n. In case the answer is very big, please output the answer mod 998244353. 
    Just in case some of you can’t understand, all the permutations of 3 are 
    1 2 3 
    1 3 2 
    2 3 1 
    2 1 3 
    3 1 2 
    3 2 1 

    InputThere are multiple test cases. 
    There are no more than 10000 test cases. 
    Each test case is an integer n(1n100000)(1≤n≤100000)
    OutputFor each test case, output the answer as described above. 

    Sample Input

    1
    2

    Sample Output

    1
    5

    Hint

  • 相关阅读:
    TCP/IP(四)网络层
    TCP/IP(二)物理层详解
    TCP/IP(一)之开启计算机网络之路
    TCP/IP中你不得不知的十大秘密
    ASP .NET Core 基本知识点示例 目录
    微服务 + Docker + Kubernetes 入门实践 目录
    ASP.NET Core 中的实时框架 SingalR
    ASP.NET Core WebAPI中使用JWT Bearer认证和授权
    .NET Core 中的通用主机和后台服务
    EF Core 实现多租户
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6783444.html
Copyright © 2011-2022 走看看