ACM-ICPC 2018 焦作赛区网络预赛G Give Candies(欧拉降幂)
Posted fy1999
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM-ICPC 2018 焦作赛区网络预赛G Give Candies(欧拉降幂)相关的知识,希望对你有一定的参考价值。
题意:给你n个东西,叫你把n分成任意段,这样的分法有几种(例如3:1 1 1,1 2,2 1,3 ;所以3共有4种),n最多有1e5位,答案取模p = 1e9+7
思路:就是往n个东西中间插任意个板子,所以最多能插n - 1个,所以答案为2^(n - 1) % p。直接套用模板
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define ll long long #define N 1000100 using namespace std; char b[N]; ll p[N]; ll a, c; ll quick(ll a, ll b){ //快速幂 ll k = 1; while(b){ if(b%2==1){ k = k*a; k %=c; } a = a*a%c; b /=2; } return k; } void priem(){ memset(p, 0, sizeof(p)); ll i, j; p[1] = 1; for(i=2; i<=sqrt(N); i++){ for(j=2; j<=N/i; j++) p[i*j] = 1; } } ll ola(ll n){ //欧拉函数 ll i, j, r, aa; r = n; aa = n; for(i=2; i<=sqrt(n); i++){ if(!p[i]){ if(aa%i==0){ r = r/i*(i-1); while(aa%i==0) aa /= i; } } } if(aa>1) r = r/aa*(aa-1); return r; } int main(){ ll d, i, j; priem(); a=2;c=1e9+7; int T; cin>>T; while(T--){ scanf("%s",b); b[strlen(b)-1]--; ll l = strlen(b); ll B=0; ll oc = ola(c); // cout<<"oc = "<<oc<<endl; for(i=0; i<l; i++){ B = B*10+b[i]-‘0‘; if(B>oc) break; } //cout<<i<<endl; if(i==l) d = quick(a,B); else{ B=0; for(i=0; i<l; i++){ //降幂 B = (B*10+b[i]-‘0‘)%oc; } d = quick(a,B+oc); } // printf("B= %I64d ",B); printf("%d ",d); } return 0; }
以上是关于ACM-ICPC 2018 焦作赛区网络预赛G Give Candies(欧拉降幂)的主要内容,如果未能解决你的问题,请参考以下文章
费马小定理+快速幂取模ACM-ICPC 2018 焦作赛区网络预赛 G. Give Candies
ACM-ICPC 2018 焦作赛区网络预赛 B题 Mathematical Curse