【NOIP模拟】细胞分裂

题面

 小 A 养了一大坨细胞。  最初小 A 只有 1 个细胞。 每秒, 小 A 的每个细胞都会分裂成 2 个细胞。  已知: 现在离“最初”已经过去了 x秒, 那么现在的细胞数当然是可以计算的。  小 A 想知道的当然不是当前的细胞数。 小 A 知道他养的细胞的习性: 每 y 个细胞会聚成一团。 经常会有剩下的细胞, 那么我们称这些细胞是孤独的。  小 A 想知道的就是孤独的细胞个数  

输入 输入文件共一行, 为两个整数 x y, 以空格隔开  

输出 输出文件共一行, 为一个整数, 即孤独的细胞个数  

【数据规模和约定】  对于 10%的数据, x<2^6。  对于 20%的数据, x<2^17。  对于 40%的数据, x<2^64。  对于 70%的数据, x<2^2333。  对于 100%的收, 0≤x<2^233333, y 是 3 到 1000 之间(含两端) 的质数

分析

题面一眼扫过去就能看出是个数学题,毕竟惊人的数据规模摆在那里。

首先快速幂一定是能暴力40分的,再高精取模能拿70分。

y是质数,2也是质数,满足互质,并且幂相当高,那就从降幂的方向考虑。

费马小定理可以降幂。假如p是质数,且gcd(a,p)=1,那么 a(p-1) ≡1(mod p)。即:假如a是整数,p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒等于1。

所以结论为:( 2^x)%y=(2^(x%(y-1)))%y

#include<bits/stdc++.h>
using namespace std;
#define N 1000010
string s;
char c[N];
int x,y;
int ksm(int a,int b,int mod)
{
    int ans=1,base=a;
    while(b)
    {
        if(b&1)
            ans=(ans*base)%mod;
        base=(base*base)%mod;
        b>>=1;
    }
    return ans;
}

int main()
{
    cin>>s>>y;
    for(int i=0;i<s.length();i++)
        x=((s[i]-'0')+x*10)%(y-1); 
    cout<<ksm(2,x,y);
}

 

posted @ 2018-08-11 00:11  WJEMail  阅读(338)  评论(0编辑  收藏  举报