dice程序解析
zby大佬的博客
密码::???为啥去那么怪的密码
∑i=1np2i(2vi∑S,i∉S|S+1|!∏x∈Spx+∑x≠ipxvx∑S,i,x∉S|S+2|!∏y∈Spy)
通过一系列的变化及
变化1
Ans=∑S|S|!∑i∈Sp2i∏x∈S,x≠ipx(2vi+∑x∈S,x≠ivx)
通过(暴力思想枚举全排列)得出ans表达式
变化2
∑i=1np2i∑S,i∉S|S+1|!(2vi∏x∈Spx+∏x∈Spx∑x∈Svx)
变化3
∑i=1np2i(2vi∑S,i∉S|S+1|!∏x∈Spx+∑x≠ipxvx∑S,i,x∉S|S+2|!∏y∈Spy)
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define MOD 998244353
using namespace std;
int n,m,f[100010],fac[100010],h[10010],a[100010],b[10010],dp[100010];
const unsigned long long limi=1e19 ;
void inc(int &x,int y) {
x+=y;
if (x>=MOD) x-=MOD;
}
void inv(int *a,int &b) {
REP(i,1,n-1) inc(a[i],MOD-1ll*b*a[i-1]%MOD);
}
void read(int &x) {
x=0;
int f=1;
char c=getchar();
for(; !isdigit(c); c=getchar()) if (c=='-') f=-f;
for(; isdigit(c); c=getchar()) x=x*10+c-'0';
x*=f;
}
int main() {
read(n);
REP(i,1,n) read(a[i]);
REP(i,1,n) read(b[i]);
fac[0]=fac[1]=1;
dp[0]=1;
REP(i,2,n) fac[i]=1ll*fac[i-1]*i%MOD;
REP(i,1,n) for(int j=n; j; --j)
inc(dp[j],1ll*dp[j-1]*b[i]%MOD);
int total=0;
REP(k,1,n) {
memcpy(f,dp,sizeof(f));
inv(f,b[k]);
unsigned long long s=0,S=0;
REP(i,0,n-1) {
s+=1ull*f[i]*fac[i+1];
if (s>=limi) s%=MOD;
}
s%=MOD;
s=2*1ull*a[k]*s%MOD;
REP(x,1,n) {
if (x==k) continue;
memcpy(h,f,sizeof(h));
inv(h,b[x]);
S=0;
REP(i,0,n-2) {
S+=1ull*h[i]*fac[i+2];
if (S>=limi) S%=MOD;
}
S%=MOD;
S=1ull*a[x]*b[x]%MOD*S%MOD;
s+=S;
}
s%=MOD;
total=(total+s*b[k]%MOD*b[k])%MOD;
}
cout<<total<<endl;
}
有点丑,astyle名副其实。。。
···
REP(i,2,n) fac[i]=1ll*fac[i-1]*i%MOD;
·····
这一段
是为了求|S+1|!与|S+2|!的阶乘, fac正常o(n);
其实吧
REP(i,1,n) for(int j=n; j; --j)
inc(dp[j],1ll*dp[j-1]*b[i]%MOD);
这一段是为了求出各个集合的概率,即求出选出其中i个的概率和
s=2*1ull*a[k]*s%MOD;
这一段是求出 2vi*s这一段
REP(i,0,n-1) {
s+=1ull*f[i]*fac[i+1];
if (s>=limi) s%=MOD;
}
这一段是为了求出∑S,i∉S|S+1|!∏x∈Spx
inv(f,b[k]);
inv是求背包。。背包要退影响。。。所以要inv (f,b[k]);
所以总结下
inv是我最不懂的地方
memcpy(f,dp,sizeof(f));
inv(f,b[k]);
unsigned long long s=0,S=0;
REP(i,0,n-1) {
s+=1ull*f[i]*fac[i+1];
if (s>=limi) s%=MOD;
}
s%=MOD;
s=2*1ull*a[k]*s%MOD;
加个部分总结
这里是求 2vi∑S,i∉S|S+1|!∏x∈Spx 即括号内前半部分。。。无奈啊
REP(x,1,n) {
if (x==k) continue;
memcpy(h,f,sizeof(h));
inv(h,b[x]);
S=0;
REP(i,0,n-2) {
S+=1ull*h[i]*fac[i+2];
if (S>=limi) S%=MOD;
}
S%=MOD;
S=1ull*a[x]*b[x]%MOD*S%MOD;
s+=S;
}
这里求的就是∑x≠ipxvx∑S,i,x∉S|S+2|!∏y∈Spy,括号里的后半段。。。
精细点解析
S+=1ull*h[i]*fac[i+2];
if (S>=limi) S%=MOD;
这里求的是嗯嗯嗯∑x≠ipxvx∑S,i,x∉S|S+2|!∏这一段
后面的
循环外的(大循环内) 是为了把S乘上 这个∏y∈Spy
S%=MOD;
S=1ull*a[x]*b[x]%MOD*S%MOD;
s+=S;
········
total=(total+sb[k]%MODb[k])%MOD;
·······
这个最后的求的是∑i=1np2i就是大括号外的那个数
最后得到total这个答案
数学代数题加公示变换加背包优化加编程思想加期望加逆元
这题目也是,,,,绝了。。。
现场怒打6行代码然后爆零。。。。
浙公网安备 33010602011771号