CF185D

大胆猜测,所有数的最大公约数一定很小:偶数时为 \(1\),奇数时为 \(2\)。设两个正整数 \(n,m\)\(n<m\),最大公约数 \(\gcd(k^{2^n}+1,k^{2^m}+1)=d\),则有 \(k^{2^n}\equiv k^{2^m} \equiv -1\pmod d,k^{2^{n+1}} \equiv (k^{2^{n+1}})^{\frac{2^m}{2^{n+1}}} \equiv k^{2^m} \equiv 1 \pmod d\),故 \(-1 \equiv 1 \pmod d\),即 \(d\) 只能为 \(1\)\(2\),当且仅当 \(k=1\)\(d=2\)

现在要求 \((k^{2^l}+1)(k^{2^{l+1}}+1)\cdots(k^{2^r}+1)\)。这个式子的意义可以理解为二进制上每一位选或不选,那么每一个 \(k\) 的幂一定恰好出现一次,则答案为 \(\dfrac{k^{2^{r+1}}-1}{k^{2^l}-1}\)。比如 \((k^1+1)(k^2+1)(k^4+1)=k^0+k^1+\cdots+k^7=\dfrac{k^8-1}{k-1}\)\(l,r+1\) 的两个分式可以消去分子)。直接使用逆元计算即可。以下是特殊情况:

  • 分母为 \(0\) 时,\(k^{2^l} \equiv 1 \pmod p\),后面 \(k\) 的幂也是同样的结果,直接输出 \(2^{r-l+1}\) 即可。
  • 使用费马小定理减小指数,注意此时模数为 \(p-1\)\(p=2\) 时不符合使用条件,直接特判即可)。
  • 如果 \(k\) 是奇数,最后再乘上 \(2^{r-l}\) 的逆元即可(乘多的部分)。
#include<iostream>
#include<cstdio>
#define int long long
using namespace std;
int k,l,r,p,n;
int qp(int a,int b,int mod){
    a=(a%mod+mod)%mod;
    int c=1;
    while(b){
        if(b&1)c=c*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return c;
}
int calc(int x){
    if(k%p==0)return 0;
    n=qp(2,x+1,p-1);
    // cout<<n<<endl;
    return qp(k,n,p);
}
signed main(){
    int T;
    cin>>T;
    while(T--){
        cin>>k>>l>>r>>p;
        if(p==2){
            if(k%2)cout<<0<<'\n';
            else cout<<1<<'\n';
            continue;
        }
        if(calc(l-1)==1){
            if(k&1)cout<<qp(2,r-l+1,p)*qp(qp(2,r-l,p),p-2,p)%p<<'\n';
            else cout<<qp(2,r-l+1,p)<<'\n';
            continue;
        }
        if(k&1)cout<<((calc(r)-1)*qp((calc(l-1)-1),p-2,p)%p*qp(qp(2,r-l,p),p-2,p)%p+p)%p<<'\n';
        else cout<<((calc(r)-1)*qp((calc(l-1)-1),p-2,p)%p+p)%p<<'\n';
    }
    return 0;
}
posted @ 2025-09-12 19:41  FormulaOne  阅读(8)  评论(0)    收藏  举报