[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;
}

反思

  1. 想了一会,但是还是很快通过。
posted @ 2025-11-17 20:42  Add_Catalyst  阅读(4)  评论(0)    收藏  举报