Solution
设 所有元素之和为 。
若 ,答案为 。
若 ,因为 各项均不大于 ,则一定存在 ,使得 经过 次循环左移后, 是安全的,且此时可把 分为 块,每一块的元素之和都恰好为 。以样例循环左移三次后为例:
1 1 -1 0 | 1 1 1 -2
此时两部分之和分别都为 。
所以对于满足 的任意 ,其实可以把它分成 块整体,循环左移时一块一块地捆绑在一起。这样 循环左移的结果只有 种,且显然它们都是安全的数列。而且易证对于确定的 ,捆绑的方式只有一种,循环左移后的数列也只有 个是安全的。
设 的长度为 倍的 ,取 ,有
这个递推公式可以通过手玩得到。由它又可推出答案
设 ,因为 最大为 ,且要对 取模,用扩展欧拉定理可得
\dfrac{p_{i+1}}{p_i}=sum^{2^k}=sum^{2^k\bmod {M-1}}\bmod MCode
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 10, mod = 998244353;
ll n, a[N], k, sum[N], ans = 0, low, cnt, len, minn[N], mini, tot;
priority_queue<int> q;
ll qpow(ll a, ll b, ll p)
{
ll res = 1;
while (b) {
if (b & 1) res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
int main()
{
scanf("%lld%lld", &n, &k);
len = 1;
for (int i = 1; i <= n; i++) {
scanf("%lld", &a[i]);
sum[i] = sum[i - 1] + a[i];
}
if (sum[n] <= 0) {
printf("0");
return 0;
}
printf("%lld", qpow(sum[n], qpow(2, k, mod - 1), mod));
return 0;
}