牛客网多校训练第一场 F - Sum of Maximum(容斥原理 + 拉格朗日插值法)

链接:

https://www.nowcoder.com/acm/contest/139/F

 

题意:

 

分析:

转载自:http://tokitsukaze.live/2018/07/19/2018niuke1.F/

 

代码:

 1 #include <cstdio>
 2 #include <cassert>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 /// 注意mod,使用前须调用一次 polysum::init(int M);
 7 namespace polysum {
 8     #define rep(i,a,n) for (int i=a;i<n;i++)
 9     #define per(i,a,n) for (int i=n-1;i>=a;i--)
10     typedef long long ll;
11     const ll mod=1e9+7; /// 取模值
12     ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
13 
14     const int D=101000; /// 最高次限制
15     ll a[D],f[D],g[D],p[D],p1[D],p2[D],b[D],h[D][2],C[D];
16     ll calcn(int d,ll *a,ll n) {
17         if (n<=d) return a[n];
18         p1[0]=p2[0]=1;
19         rep(i,0,d+1) {
20             ll t=(n-i+mod)%mod;
21             p1[i+1]=p1[i]*t%mod;
22         }
23         rep(i,0,d+1) {
24             ll t=(n-d+i+mod)%mod;
25             p2[i+1]=p2[i]*t%mod;
26         }
27         ll ans=0;
28         rep(i,0,d+1) {
29             ll t=g[i]*g[d-i]%mod*p1[i]%mod*p2[d-i]%mod*a[i]%mod;
30             if ((d-i)&1) ans=(ans-t+mod)%mod;
31             else ans=(ans+t)%mod;
32         }
33         return ans;
34     }
35     void init(int M) { /// M:最高次
36         f[0]=f[1]=g[0]=g[1]=1;
37         rep(i,2,M+5) f[i]=f[i-1]*i%mod;
38         g[M+4]=powmod(f[M+4],mod-2);
39         per(i,1,M+4) g[i]=g[i+1]*(i+1)%mod;
40     }
41     ll polysum(ll n,ll *arr,ll m) { // a[0].. a[m] \sum_{i=0}^{n-1} a[i]
42         for(int i = 0; i <= m; i++) a[i] = arr[i];
43         a[m+1]=calcn(m,a,m+1);
44         rep(i,1,m+2) a[i]=(a[i-1]+a[i])%mod;
45         return calcn(m+1,a,n-1);
46     }
47     ll qpolysum(ll R,ll n,ll *a,ll m) { // a[0].. a[m] \sum_{i=0}^{n-1} a[i]*R^i
48         if (R==1) return polysum(n,a,m);
49         a[m+1]=calcn(m,a,m+1);
50         ll r=powmod(R,mod-2),p3=0,p4=0,c,ans;
51         h[0][0]=0;h[0][1]=1;
52         rep(i,1,m+2) {
53             h[i][0]=(h[i-1][0]+a[i-1])*r%mod;
54             h[i][1]=h[i-1][1]*r%mod;
55         }
56         rep(i,0,m+2) {
57             ll t=g[i]*g[m+1-i]%mod;
58             if (i&1) p3=((p3-h[i][0]*t)%mod+mod)%mod,p4=((p4-h[i][1]*t)%mod+mod)%mod;
59             else p3=(p3+h[i][0]*t)%mod,p4=(p4+h[i][1]*t)%mod;
60         }
61         c=powmod(p4,mod-2)*(mod-p3)%mod;
62         rep(i,0,m+2) h[i][0]=(h[i][0]+h[i][1]*c)%mod;
63         rep(i,0,m+2) C[i]=h[i][0];
64         ans=(calcn(m,C,n)*powmod(R,n)-c)%mod;
65         if (ans<0) ans+=mod;
66         return ans;
67     }
68 }
69 
70 typedef long long int LLI;
71 const LLI MOD = polysum::mod;
72 const int UP = 1e3 + 5;
73 LLI a[UP], b[UP];
74 
75 int main() {
76     polysum::init(UP);
77     int n;
78     while(~scanf("%d", &n)) {
79         for(int i = 1; i <= n; i++) scanf("%lld", &a[i]);
80         sort(a+1, a+n+1);
81         LLI ans = 0, prod = 1;
82         for(int i = 1; i <= n; i++) {
83             if(a[i] == a[i-1]) {
84                 prod = prod * a[i] % MOD;
85                 continue;
86             }
87             for(int x = 1; x <= n-i+1; x++) {
88                 b[x] = (polysum::powmod(x, n-i+1) - polysum::powmod(x-1, n-i+1) + MOD) % MOD * x % MOD;
89             }
90             LLI temp = (polysum::polysum(a[i]+1, b, n-i+1) - polysum::polysum(a[i-1]+1, b, n-i+1) + MOD) % MOD;
91             ans = (ans + prod * temp % MOD) % MOD;
92             prod = prod * a[i] % MOD;
93         }
94         printf("%lld\n", ans);
95     }
96     return 0;
97 }

 

拉格朗日插值法模板(杜教版):

 1 /// 注意mod,使用前须调用一次 polysum::init(int M);
 2 namespace polysum {
 3     #define rep(i,a,n) for (int i=a;i<n;i++)
 4     #define per(i,a,n) for (int i=n-1;i>=a;i--)
 5     typedef long long ll;
 6     const ll mod=1e9+7; /// 取模值
 7     ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
 8 
 9     const int D=101000; /// 最高次限制
10     ll a[D],f[D],g[D],p[D],p1[D],p2[D],b[D],h[D][2],C[D];
11     ll calcn(int d,ll *a,ll n) {
12         if (n<=d) return a[n];
13         p1[0]=p2[0]=1;
14         rep(i,0,d+1) {
15             ll t=(n-i+mod)%mod;
16             p1[i+1]=p1[i]*t%mod;
17         }
18         rep(i,0,d+1) {
19             ll t=(n-d+i+mod)%mod;
20             p2[i+1]=p2[i]*t%mod;
21         }
22         ll ans=0;
23         rep(i,0,d+1) {
24             ll t=g[i]*g[d-i]%mod*p1[i]%mod*p2[d-i]%mod*a[i]%mod;
25             if ((d-i)&1) ans=(ans-t+mod)%mod;
26             else ans=(ans+t)%mod;
27         }
28         return ans;
29     }
30     void init(int M) { /// M:最高次
31         f[0]=f[1]=g[0]=g[1]=1;
32         rep(i,2,M+5) f[i]=f[i-1]*i%mod;
33         g[M+4]=powmod(f[M+4],mod-2);
34         per(i,1,M+4) g[i]=g[i+1]*(i+1)%mod;
35     }
36     ll polysum(ll n,ll *arr,ll m) { // a[0].. a[m] \sum_{i=0}^{n-1} a[i]
37         for(int i = 0; i <= m; i++) a[i] = arr[i];
38         a[m+1]=calcn(m,a,m+1);
39         rep(i,1,m+2) a[i]=(a[i-1]+a[i])%mod;
40         return calcn(m+1,a,n-1);
41     }
42     ll qpolysum(ll R,ll n,ll *a,ll m) { // a[0].. a[m] \sum_{i=0}^{n-1} a[i]*R^i
43         if (R==1) return polysum(n,a,m);
44         a[m+1]=calcn(m,a,m+1);
45         ll r=powmod(R,mod-2),p3=0,p4=0,c,ans;
46         h[0][0]=0;h[0][1]=1;
47         rep(i,1,m+2) {
48             h[i][0]=(h[i-1][0]+a[i-1])*r%mod;
49             h[i][1]=h[i-1][1]*r%mod;
50         }
51         rep(i,0,m+2) {
52             ll t=g[i]*g[m+1-i]%mod;
53             if (i&1) p3=((p3-h[i][0]*t)%mod+mod)%mod,p4=((p4-h[i][1]*t)%mod+mod)%mod;
54             else p3=(p3+h[i][0]*t)%mod,p4=(p4+h[i][1]*t)%mod;
55         }
56         c=powmod(p4,mod-2)*(mod-p3)%mod;
57         rep(i,0,m+2) h[i][0]=(h[i][0]+h[i][1]*c)%mod;
58         rep(i,0,m+2) C[i]=h[i][0];
59         ans=(calcn(m,C,n)*powmod(R,n)-c)%mod;
60         if (ans<0) ans+=mod;
61         return ans;
62     }
63 }

 

posted @ 2018-08-06 23:54  Ctfes  阅读(496)  评论(0编辑  收藏  举报