NOIP T2 题解

https://www.luogu.com.cn/problem/P11362
参考这篇题解做的,也是参考它写的。
我们令能放下 x 个二元限制,两端有一元限制的区间的方案数是 f(x)

我们考虑限制的第一个数字是左端点的值,那么就有 v 种取法(因为 a 固定, bv 种取法),然后还剩下 f(x-1) ,用乘法原理就是 v\times f(x-1)

我们考虑不是的情况,就是限制第一个数有 v-1 种第二个有 v 种,其他随便取,那么就是:

v\times(v-1)\times v^{2x-2}

=v^{2x-1}\times(v-1)

=v^{2x-1}\times v-v^{2x-1}

=v^{2x}-v^{2x-1}

那么 f(x)=v^{2x}-v^{2x-1}+v\times f(x-1)

其中边界条件是 f(1)=v^2-v+1

我们把 f(x-1) 展开:

f(x)=v^{2x}-v^{2x-1}+v\times((v^{2x-2}-v^{2x-3})\times v\times f(x-2))

f(x)=v^{2x}-v^{2x-1}+v^{2x-1}-v^{2x-2}+v^2\times f(x-2)

f(x)=v^{2x}-v^{2x-2}+v^2\times f(x-2)

再展开:

f(x)=v^{2x}-v^{2x-2}+v^2\times (v^{2x-4}-v^{2x-5}+v\times f(x-3))

f(x)=v^{2x}-v^{2x-2}+v^{2x-2}-v^{2x-3}+v^3\times f(x-3)

f(x)=v^{2x}-v^{2x-3}+v^3\times f(x-3)

你发现规律了吗,我们不断展开就是: f(x)=v^{2x}-v^{2x-y}+v^y\times f(x-y)

接下来我们把 y=x-1 代录算式:

f(x)=v^{2x}-v^{x+1}+v^{x-1}\times f(1)

f(x)=v^{2x}-v^{x+1}+v^{x-1}\times(v^2-v+1)

f(x)=v^{2x}-v^{x+1}+v^{x+1}-v^x+v^{x-1}

f(x)=v^{2x}-v^{x}+v^{x-1}

我们先按 c_i 排序。

答案就是就是对于所有一原限制得出的 \displaystyle\prod_{i=2}^{n}f(c_i-c_{i-1})\times v^{2\times(c_1-1)}\times v^{2\times(n-c_m)} 。解释一下后面的,是开头的还没有到 c_1 的那一个区间和$c_m$ 没有到结尾的那一段区间。

还有一些细节:

1.如果前后两 c_i 相同但是 d_i 不同,那么无解,若 d_i 想同则跳过不能重复计算。

2. 记得随时取模,计算的时候有减法,要取模后加上模数再取模。

核心代码:

for(int i=2;i<=m;++i)
{
	if(a[i-1].x==a[i].x&&a[i-1].y!=a[i].y)//如果出现位置相同但是值不同,那么无解 
	{
		flag=0;
		cout<<0<<endl;
		break;
	}
	if(a[i-1].x==a[i].x) continue;//要去重 
	ans=ans*calc(a[i].x-a[i-1].x)%Mod;//处理中间 
}
if(!flag) continue;
ans=ans*qpow(v,2*(a[1].x-1))%Mod;//处理开头 
ans=ans*qpow(v,2*(n-a[m].x))%Mod;//处理结尾 
cout<<ans<<endl; 
2 个赞