省选模拟总结

数学专题测试1:
T1 exLucas板子 不会就没什么好说的
T2 50pts 异或FWT板子 不会就没什么好说的

满分做法:先把原序列变成点值表达式,然后点值比较好的性质是可以直接运算。

问题等价于求$ans=\sum\limits_{i=0}^{p} x^{2^i}$,然后注意到模数很小,直接倍增就行了。

顺便放下FWT板子(

 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 const int mod=998244353,inv=499122177;
 5 int n,m,a[1<<18],b[1<<18],ta[1<<18],tb[1<<18];
 6 inline int read() {
 7     int x=0;char c=getchar(),f=0;
 8     for(;c>'9'||c<'0';c=getchar()) f=c=='-';
 9     for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-48;
10     return f?-x:x;
11 }
12 inline void moded(int &x) {
13     if(x<0) x+=mod; if(x>=mod) x-=mod;
14 }
15 inline void and_FWT(int *f,int *g,int opt=1) {
16     for(int i=0;i<m;++i) g[i]=f[i];
17     for(int i=2;i<=m;i<<=1)
18         for(int st=0;st<m-1;st+=i)
19             for(int j=st;j<st+i/2;++j)
20                 moded(g[j]+=g[j+i/2]*opt);
21     return ;
22 }
23 inline void or_FWT(int *f,int *g,int opt=1) {
24     for(int i=0;i<m;++i) g[i]=f[i];
25     for(int i=2;i<=m;i<<=1)
26         for(int st=0;st<m-1;st+=i)
27             for(int j=st;j<st+i/2;++j)
28                 moded(g[j+i/2]+=g[j]*opt);
29     return ;
30 }
31 inline void xor_FWT(int *f,int *g,int opt=1) {
32     for(int i=0;i<m;++i) g[i]=f[i];
33     for(int i=2;i<=m;i<<=1) 
34         for(int st=0;st<m-1;st+=i)
35             for(int j=st;j<st+i/2;++j) {
36                 int u=g[j],t=g[j+i/2];
37                 if(opt) moded(g[j]=u+t),moded(g[j+i/2]=u-t);
38                 else g[j]=1ll*(u+t)*inv%mod,g[j+i/2]=1ll*(u-t)*inv%mod;
39             }
40     return ;
41 }
42 int main() {
43     m=1<<(n=read());
44     for(int i=0;i<m;++i) a[i]=read();
45     for(int i=0;i<m;++i) b[i]=read();
46     or_FWT(a,ta),or_FWT(b,tb);
47     for(int i=0;i<m;++i) ta[i]=1ll*ta[i]*tb[i]%mod;
48     or_FWT(ta,ta,-1);
49     for(int i=0;i<m;++i) printf("%d ",ta[i]);puts("");
50     and_FWT(a,ta),and_FWT(b,tb);
51     for(int i=0;i<m;++i) ta[i]=1ll*ta[i]*tb[i]%mod;
52     and_FWT(ta,ta,-1);
53     for(int i=0;i<m;++i) printf("%d ",ta[i]);puts("");
54     xor_FWT(a,ta),xor_FWT(b,tb);
55     for(int i=0;i<m;++i) ta[i]=1ll*ta[i]*tb[i]%mod;
56     xor_FWT(ta,ta,0);
57     for(int i=0;i<m;++i) printf("%d ",(ta[i]+mod)%mod);
58     return 0;
59 }
View Code

T3 大神期望题

和三华聚顶很像,但我当时就没改出来233,看数据范围是区间DP。

先断环成链,这种题倒退很难,考虑正着推。

设f[i][j]表示区间[i,j-1]均被安排好了,j还未被安排的期望。

枚举最后一个被安排的k,基本的就是f[i][j]等于每个可能k的贡献累加,但是最后安排每个k的概率又不一样。

所以现在问题是求p(i,j,k)即在区间i,j中除了j最后一个是k的概率。

顺便设$g[i][j]=\sum\limits_{k=i}^{j-1} p(i,j,k)$即搞到[i,j]区间且实现了f[i][j]的概率

如果能求出来,那么直观地想有$f[i][j]=\sum\limits_{k=i}^{j-1} p(i,j,k)*(f[i][k]+f[k+1][j]+cost(i,k))$

上面的柿子其实是有问题的,后面那一坨每一项表示的是在k对[i,j]的贡献,但是所有k的概率总和不是1,所以要除一个$g[i][j]$表示期望。

其实还挺好理解的,把概率看成方案,这就是一个加权平均数。

好了,现在的问题集中到了求(p,i,j,k)上

一开始想的是GPBS

现在应该理解一下g[i][j],f[i][j]

g[i][j]是基于所有操作均落在[i,j]内的概率,都是区间合并,所以肯定只考虑了区间内部。

f[i][j]是单纯的一个期望,因为如果把概率看成方案的话,这是一个很纯的加权平均数。

重新定义:

g[i][j]表示所有操作均落在区间[i,j]且区间[i,j-1]安排好,j点未安排的方案除以所有操作均落在区间[i,j]的总方案

f[i][j]表示所有操作均落在区间[i,j]且区间[i,j-1]安排好,j点未安排的方案的代价总和除于方案数。

然后p(i,j,k)就显然了。k作为分割点尚未被安排,那么k左右两侧一定是分别独立的。

假设ls是[i,k-1]的"."的个数,rs是[k+1,j]的"."的个数

直接有柿子:$p(i,j,k)=C_{ls+rs+1}^{ls} g[i][k] (k-i+1)^{ls+1} g[k+1][j] (j-k)^{rs}/(j-i+1)^{ls+rs+1}$

猜你喜欢

转载自www.cnblogs.com/hzoi-kx/p/12151847.html