吐槽一句:这样例纯 10Q 吧
对于任意两个位置 满足 ,其 为:。设这个值为 ,那么有 ,又因为 ,所以 即 。因此可以确定 即 。简单分类即可得到 当且仅当 是奇数, 当且仅当 是偶数。
然后这个题就做完了:求 可以先求出所有数的连乘积,然后再除掉这些数的共同因子。有必有除共同因子当且仅当 即 ,直接除以 即可。而前面的连乘积形如:
考虑给这个东西变换一下形式,得到:
这个东西看上去十分眼熟,考虑初一数学的经典技巧,在前面补一项 然后平方差消过去,最终得到上面式子的值为:
可以在 的时间复杂度内用快速幂和逆元计算。最后记得 的时候把答案除以公约数部分的 。
#pragma GCC optimize(3, "Ofast", "inline", "unroll-loops")
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000010;
const int inf = 1e18;
int k, l, r, p;
inline int power(int a, int b, int c)
{
a %= c;
int ans = 1;
while (b)
{
if (b & 1)
ans = ans * a % c;
a = a * a % c, b >>= 1;
}
return ans;
}
inline int inversion(int x) { return power(x, p - 2, p); }
int a[N], fa[N], siz[N];
inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
inline void merge(int x, int y)
{
x = find(x), y = find(y);
if (x != y)
fa[x] = y, siz[y] += siz[x];
}
signed main()
{
cin.tie(0)->sync_with_stdio(false);
int T;
cin >> T;
while (T--)
{
cin >> k >> l >> r >> p;
if (p == 2)
{
cout << (1 ^ (k & 1)) << '\n';
continue;
}
int dz = 0;
if (k % p)
dz = power(k, power(2, l, p - 1), p);
int res = power(2, r - l + 1, p), dzr = 0;
if (k % p)
dzr = power(k, power(2, r + 1, p - 1), p);
if (dz != 1)
res = power((dz + p - 1) % p, p - 2, p) * (dzr + p - 1) % p;
if (k & 1)
res = res * power(power(2, r - l, p), p - 2, p) % p;
cout << res << '\n';
}
return 0;
}
喜欢的话,留下你的评论吧~