[NOIP2024] 遗失的赋值 题解
[NOIP2024] 遗失的赋值 题解
知识点
组合数学。
分析
首先判断一下数据合法性,然后 \(d\) 就没有了用处。
将 \(c\) 排序,发现可以容斥一下,统计方案只需考虑相邻两个数之间的关系和首尾的特殊处理。
那么相邻两个数之间的关系可以考虑容斥,把 \(v^{2(c_{i+1}-c_i)}\) 中减去 \((v-1)v^{c_{i+1}-c_i}\) 即可,表示不会是从 \(d_i\) 出发连到不为 \(d_{i+1}\) 的数。
代码
constexpr int M(1e5+10);
int Cas,n,m,v,ans;
struct node {
int c,d;
friend bool operator <(node a,node b) {
return a.c<b.c;
}
} a[M];
int Cmain() {
/*Input*/
I(n,m,v),ans=1;
FOR(i,1,m)I(a[i].c,a[i].d);
sort(a+1,a+m+1);
FOR(i,1,m-1)if(a[i].c==a[i+1].c&&a[i].d!=a[i+1].d)return puts("0"),0;
if(a[1].c>1)tomul(ans,Pow(v,2*(a[1].c-1)));
FOR(i,1,m-1)if(a[i].c!=a[i+1].c) {
int val(add(
Pow(v,2*(a[i+1].c-a[i].c)),
Mod-mul(v-1,Pow(v,a[i+1].c-a[i].c-1))
));
tomul(ans,val);
}
if(a[m].c<n)tomul(ans,Pow(v,2*(n-a[m].c)));
O(ans,'\n');
return 0;
}
int main() {
#ifdef Plus_Cat
freopen(Plus_Cat ".in","r",stdin),freopen(Plus_Cat ".out","w",stdout);
#endif
for(I(Cas); Cas; --Cas)Cmain();
return 0;
}
反思
- 想了一会,但是还是很快通过。

浙公网安备 33010602011771号