题目link:https://www.luogu.com.cn/problem/P6202
本题推式子即可。
首先先模拟一下密码更新的过程,设一共有 $n$ 头牛,密码初始值分别为 $c[1]$ , $c[2]$ , $c[3]$ , $...$ , $c[n]$,密码初始的总和为$sum$(以后的式子都用初始值表达,也就是说这些参数不会更新);
这里只给了最后的结果,中间过程省略,但是注意这里有些是需要因式分解得出的。
第一次更新:
$c[i]$ $=$ $sum$ $-$ $c[i]$;
$sum$ $=$ $sum$ $*$ $(n$ $-$ $1)$;
第二次更新:
$c[i]$ $=$ $sum$ $*$ $(n$ $-$ $2)$ $+$ $c[i]$;
$sum$ $=$ $sum$ $*$ $(n$ $-$ $1)$2;
第三次更新:
$c[i]$ $=$ $sum$ $*$ $(n$2 $-$ $3$ $*$ $n$ $+$ $3)$ $-$ $c[i]$;
$sum$ $=$ $sum$ $*$ $(n$ $-$ $1)$3;
第四次更新:
$c[i]$ $=$ $sum$ $*$ $(n$3 $-$ $4$ $*$ $n$2 $+$ $6$ $*$ $n$ $-$ $4)$ $+$ $c[i]$;
$sum$ $=$ $sum$ $*$ $(n$ $-$ $1)$4;
………………
通过模拟发现第偶数次更新时,$c[i]$ 的值中有一项是 $+$ $c[i]$,而其他项都与 $c[i]$ 无关,这样计算更新后 $c[i]$ 的值与 $c[i]$ 的差,都是一样的。而找规律发现 $sum$ 的值是有规律的,因此计算出更新后的 $sum$ 与 $sum$ 的差值然后除以 $n$,就是一个 $c[i]$ 更新的值,输出 $c[i]$ $+$ 这个值即可;如果是奇数次更新的话,那么先偶数次更新,再按题意模拟一下即可。公式也就能写出来了,就是$c[i]$ $+$ $sum$ $*$ $[(n$ $-$ $1)$T $-$ $1]$ $/$ $n$。(注意判断奇偶)
$code$(目前有点$bug$,只有$20$分):
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define MOD 98765431 4 #define ll long long 5 using namespace std; 6 int T, n; 7 ll c[50010], sum; 8 ll ksm(int x, int y) 9 { 10 ll ans = 1; 11 for(; y; y >>= 1, x = x * x % MOD) 12 if(y & 1) 13 ans = ans * x % MOD; 14 return ans; 15 } 16 int main() 17 { 18 scanf("%d %d", &n, &T); 19 for(int i = 1; i <= n; ++i) 20 scanf("%lld", &c[i]), sum += c[i], sum %= MOD; 21 if(T & 1) 22 { 23 for(int i = 1; i <= n; ++i) 24 printf("%lld ", (sum * ksm(n - 1, T - 1) % MOD - (c[i] + sum * (ksm(n - 1, T - 1) - 1) / n % MOD) % MOD) % MOD); 25 } 26 else 27 { 28 for(int i = 1; i <= n; ++i) 29 printf("%lld ", (c[i] + sum * (ksm(n - 1, T) - 1) / n) % MOD); 30 } 31 return 0; 32 }