【ARC133E】Cyclic Medians(数学)

Cyclic Medians

题目链接:ARC133E

题目大意

给你四个数 n,m,v,a,然后你可以选择两个长度分别为 n,m,值域在 1~v 之间的数组 x,y。
有一个数 A 初始值为 a,然后进行 nm 次变换,第 i 次把 A,x[(i-1)%n+1],y[(i-1)%m+1] 的中值作为新的 A。
问你对于每一对可能的数组 x,y,求 A 的最终值的和。

思路

直接求不好搞,考虑对于每个 k k k 求有多少种情况的贡献 ⩾ k \geqslant k k
⩾ k \geqslant k k 的数变成 1 1 1 < k <k <k 的数变成 0 0 0

于是只有 0 , 1 0,1 0,1 问题看上去似乎可以做了。
发现如果 ( a , 0 , 0 ) (a,0,0) (a,0,0) 或者 ( a , 1 , 1 ) (a,1,1) (a,1,1) 这种出现了,那就跟 a a a 没关系了。
我们就只需要看看最后是 0 0 0 还是 1 1 1
然后其实有一个东西叫做对称性,就是 k = p k=p k=p 的时候 0 0 0 的个数和 k = v − p k=v-p k=vp 的时候 1 1 1 的个数是一样的。
k k k 等于啥的时候贡献都是 1 1 1,所以我们只需要求出所有 k k k a a a 无关的情况数,除二即可。

接着考虑数跟 a a a 有关的情况数,无关的数量可以用全部减去有关的。
那就是全程都是 ( a , 0 , 1 ) (a,0,1) (a,0,1) 这种。
那因为有循环,所以独立的行和列只有 gcd ⁡ ( n , m ) \gcd(n,m) gcd(n,m) 个。
别的会因为能匹配到而要求相同。(匹配你把所有左侧点的 ( i − 1 ) % n + 1 (i-1)\%n+1 (i1)%n+1,跟右侧点的 ( i − 1 ) % m + 1 (i-1)\%m+1 (i1)%m+1 连边, 表示这些之间要不同)
(然后由于是二分图,一个连通块中左侧点和右侧点分别都要一样,而且互相之间还要不同,所以是固定了)
然后再根据谁是 0 0 0 谁是 1 1 1,能统计方案:
( k n / gcd ⁡ ( v − k ) m / gcd ⁡ + ( v − k ) n / gcd ⁡ k m / gcd ⁡ ) gcd ⁡ (k^{n/\gcd}(v-k)^{m/\gcd}+(v-k)^{n/\gcd}k^{m/\gcd})^{\gcd} (kn/gcd(vk)m/gcd+(vk)n/gcdkm/gcd)gcd
(里面每一组可以选的,然后有 gcd ⁡ \gcd gcd 组独立的)

然后就好啦。

代码

#include<cstdio>
#define ll long long
#define mo 998244353

using namespace std;

int n, m, v, a, g;
ll ans;

ll gcd(ll x, ll y) {
	if (!y) return x;
	return gcd(y, x % y);
}

ll ksm(ll x, ll y) {
	ll re = 1;
	while (y) {
		if (y & 1) re = re * x % mo;
		x = x * x % mo; y >>= 1;
	}
	return re;
}

int main() {
	scanf("%d %d %d %d", &n, &m, &v, &a); g = gcd(n, m);
	
	ll all = ksm(v, n + m), inv2 = (mo + 1) / 2;
	ans += all;
	for (int lim = 2; lim <= v; lim++) {
		ll num_no = ksm((ksm(lim - 1, n / g) * ksm(v - lim + 1, m / g) % mo + ksm(v - lim + 1, n / g) * ksm(lim - 1, m / g) % mo) % mo, g);
		if (a >= lim) (ans += num_no) %= mo;
		ll num_yes = (all - num_no + mo) % mo;
		(ans += num_yes * inv2 % mo) %= mo;
	}
	printf("%lld", ans);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值