Hdu 5322 2015多校对抗赛三

Hope

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 152    Accepted Submission(s): 58


Problem Description
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,...An , now we define its value as below:
For each  Ai , if there exists a minimum  j  satisfies  j>i  and  Aj>Ai  , then connect an edge between  Ai  and  Aj  , 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
 

Input
There are multiple test cases.
There are no more than 10000 test cases.
Each test case is an integer n (1n100000) .
 

Output
For each test case, output the answer as described above.

 

Sample Input
  
  
1 2
 

Sample Output
  
  
1 5
 

Author
ZSTU
 

Source
 

题意:

求集合的值。对于一个集合,有n!种排列,对每种排列,有一个值,集合的值为这些排列的值求和。

排列值:先对排列建边,Ai连接与他最近的Aj  满足 Ai<Aj  && i<j  就会得到m个不连通块。

排列值即为这些不连通块节点个数的积的平方。m1^2*m2^2*.....mm^2 或则 (m1*m2*....*mm)^2

做法:动态规划。

有个特性,假设集合最大值x在位置i上,那么i位置肯定与前面所有点连通。因为比x小的点都逃不过i的管辖,不可能到i后面去。

因此我们队最大值所在的位置坐动归。

dp[i]表示最大值x在i位置时,集合的值。

那么  dp[i]=sigma( C(n-1,i-1)*(i-1)!*i^2*(dp[n-i]))

次意义是可以在n-1个剩下的数中选择i-1个数放在i位置前面,那么所有情况为C(n-1,i-1)*(i-1)!,值得话在乘以i^2(个数为i)

i后面的值为dp[n-i]。写博客突然想到的转移,记下来吧,毕竟不是搞dp的我。但是这个dp然并卵。

正确的dp为:

dp[i]表示排列长度为i的时候值,下面 j 的意义为最大值的位置。

那么dp[i]=sigma(C(i-1,j-1)*(j-1)!*j^2*dp[i-j] )

最大值位置在j,从剩下的i-1个数里面选择j-1个数放在j的前面,有C(i-1,j-1)*(j-1)!种情况,乘以j^2即为这个连通块的值。

j位置后面的连通块乘积为dp[i-j]。所以dp[i]为枚举j位置的和。

最后dp[n]即为n大小集合的值。

但是这个转移是n^2的,必须T。

把转移化简:

dp[i]=sigma( (i-1)!/(i-j)!/(j-1)! *(j-1)! *j^2*dp[i-j]  ) = sigma( (i-1)!/(i-j)! * j^2 *dp[i-j]   ) = (i-1)! * sigma ( j^2*dp[i-j] / (i-j)! )

取出  j^2 * dp[i-j] / (i-j)!  令k=i-j,k的范围是0-i,如此一来可以求和去掉sigma了。

(i-k)^2 * dp[k]/k! = i^2*dp[k]/k! - 2ikdp[k]/k! + k^2dp[k]/k!

可以用三个整数保存加粗部分。

#include<iostream>
#include<cstdio>
using namespace std;
#define LL long long
#define MOD 998244353
#define maxn 100000
LL dp[maxn+10];
LL jie[maxn+10];
LL inv[maxn+10];
LL power(LL x,LL k){
    LL res=1;
    while(k){
        if(k&1)res=res*x%MOD;
        x=x*x%MOD;
        k>>=1;
    }
    return res;
}
void init(){
    jie[0]=jie[1]=1;
    inv[0]=inv[1]=1;
    for(int i=2;i<=maxn;i++){
        jie[i]=i*jie[i-1]%MOD;
        inv[i]=power(jie[i],MOD-2);
    }
}
void solve(){
    init();
    dp[0]=0;
    dp[1]=1;
    LL a=2,b=1,c=1;//从0开始
    for(LL i=2;i<=maxn;i++){//i要LL,否则i*i会爆
        dp[i]=jie[i-1]*(i*i%MOD*a%MOD-2*i*b%MOD+c%MOD+MOD)%MOD;
        a=(a+dp[i]*inv[i]%MOD)%MOD;
        b=(b+i*dp[i]%MOD*inv[i]%MOD)%MOD;
        c=(c+i*i%MOD*dp[i]%MOD*inv[i]%MOD)%MOD;
    }
}
int main(){
    solve();
    int n;
    while(~scanf("%d",&n))
        printf("%lld\n",dp[n]);
    return 0;
}




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值