NOIP模拟 Math 【同余】

来源:互联网 发布:制谱软件x 编辑:程序博客网 时间:2024/06/05 16:32

题目大意:

给出a,n,求有多少个正整数b满足abba(mod 2n),(1n301a109);

解题思路:

再一次认识到了打表找规律的重要性。

显然ab奇偶要相同。

对于a为奇数的情况,打表就可以发现,b唯一(b=aba(mod 2n))。

而对于a为偶数的情况,b也一定是偶数。
bn,则ab0(mod 2n),所以ba0(mod 2n),设b=(2kc)(c为奇数),则(2kc)a0(mod 2n),所以2ka2n,所以kank(n+a1)/a,所以b一定是2(n+a1)/a的倍数。
b<n,直接枚举快速幂即可。

#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<set>#define ll long longusing namespace std;int getint(){    int i=0,f=1;char c;    for(c=getchar();(c<'0'||c>'9')&&c!='-';c=getchar());    if(c=='-')f=-1,c=getchar();    for(;c>='0'&&c<='9';c=getchar())i=(i<<3)+(i<<1)+c-'0';    return i*f;}int T,n;int ksm(int x,int y){    int res=1;    for(;y;y>>=1,x=1ll*x*x%(1<<n))        if(y&1)res=1ll*res*x%(1<<n);    return res;}int main(){    //freopen("math.in","r",stdin);    //freopen("math.out","w",stdout);    int a,b;    T=getint();    while(T--)    {        a=getint(),n=getint();        if(a&1)        {            puts("1");            continue;        }        int ans=0;        for(b=1;b<=n;b++)            if(ksm(b,a)==ksm(a,b))ans++;        int k=(n+a-1)/a;        ans+=((1<<n)>>k)-(n>>k);        cout<<ans<<'\n';    }    return 0;}