【空洞骑士】容斥区间差分dp
Magic_World · · 个人记录
【空洞骑士】容斥区间差分dp
光芒浸透圣巢,她正犯下弥天之错。
所剩寥寥无几的信仰,为什么始终执着。
我将作灯塔,照耀王国。
但在那之前有更重要的事去做,
无论什么代价都在所不惜,尽管我所剩无多……
白王正在最后一次参观他建造的宏伟宫殿。现在假设宫殿由
白王提出了
输入格式
第一行,两个整数
接下来
接下来
输出格式
反向思考,对于每一个
而本题中
for(int k=1;k<=Maxm;++k)
{
for(int s=1;s<=n;++s)
{
for(int v=1;v<=n;++v)
{
f[k][s][L[v]]+=f[k-1][s][v];
f[k][s][R[v]+1]-=f[k-1][s][v];//差分
}
for(int t=0;t<=n;++t)
{
f[k][s][t]+=f[k][s][t-1];//差分求和
}
}
}
再考虑不经过
感性上考虑,经过
但是这之中有重复方案,例如 : abcabcabc
每个c都可以作为中转点,但三个 c 的方案是一模一样的。
那么如何排除重复情况呢?
注意到,强制要求中转点的 c 是这条路上最后一次经过 c ,即可排除重复。
设
注意,初始化时
转移同理
代码
for(int s=1;s<=n;++s)
{
f[0][s][s]=1,g[0][s][s]=1;//初始化
}
for(int k=1;k<=M;++k)
{
for(int s=1;s<=n;++s)
{
for(int v=1;v<=n;++v)
{
f[k][s][L[v]]+=f[k-1][s][v];
f[k][s][R[v]+1]-=f[k-1][s][v];
g[k][s][L[v]]+=g[k-1][s][v];
g[k][s][R[v]+1]-=g[k-1][s][v];
}
for(int t=0;t<=n;++t)//注意区间有[0,0]
{
f[k][s][t]+=f[k][s][t-1];
g[k][s][t]+=g[k][s][t-1];
}
g[k][s][s]=0;//保证不经过第二次 s
}
}