poj2154Color polya定理+欧拉函数优化
生活随笔
收集整理的這篇文章主要介紹了
poj2154Color polya定理+欧拉函数优化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
沒想到賤賤的數據居然是錯的。。搞得我調了一中午+晚上一小時(哦不d飛LJH掉RP畢竟他是BUFF)結果重判就對了五次。。
回歸正題,這題傻子都看得出是polya定理(如果你不是傻子就看這里),還沒有翻轉,就一個旋轉,結果我就歡快的打完交上去了。傻子都知道會TLE,n<=1e9啊,O(n)都原地爆炸,那怎么辦。。。一臉懵逼(然后就膜題解了)
可以發現,這題公式就是sigma(gcd(k,n))(k=1~n),然后該怎么優化呢,我(??)發現gcd(k,n)里面肯定有一些k和n的gcd是相同的,那我們設n=i*gcd,k=j*gcd,那i肯定和j互質并且1<=j<=i,而且可以發現,gcd(i*gcd,j*gcd)=gcd,只要知道j有多少個,就讓power(n,n/i)乘上這個個數,那gcd=n/i的所有情況就都解決了,那具體j有多少個呢?顯而易見(??)就是歐拉函數值(然而我不會)了,那我們O(sqrt(n))枚舉i,然后就可以得出gcd,然后就可以求出歐拉函數值,那就是phi(i)*power(n,n/i)
#include<cstdio> #include<cstring> #include<cmath> using namespace std; bool v[1100000]; int pr,prime[1100000]; void linear_prime() {memset(v,true,sizeof(v));for(int i=2;i<=1000000;i++){if(v[i]==true)prime[++pr]=i;for(int j=1;j<=pr&&i*prime[j]<=1000000;j++){v[i*prime[j]]=false;if(i%prime[j]==0)break;}} } int n,mod; int power(int A,int k) {int ans=1;A%=mod;while(k!=0){if(k%2==1)ans=(ans*A)%mod;A=(A*A)%mod;k/=2;}return ans; } int phi(int x)//求歐拉函數值,即j的種數 {int ans=x;for(int i=1;prime[i]*prime[i]<=x;i++){if(x%prime[i]==0){ans=ans-ans/prime[i];while(x%prime[i]==0)x/=prime[i];}}if(x!=1)ans=ans-ans/x;return ans%mod; } int main() {linear_prime();int T;scanf("%d",&T);while(T--){scanf("%d%d",&n,&mod);int ans=0;//設n=i*gcd 而 k=j*gcd,用歐拉函數將所有j的值求出 for(int i=1;i*i<=n;i++){if(n%i==0){ans=(ans+phi(i)*power(n,n/i-1))%mod;//循環節為gcdif(i*i!=n)ans=(ans+phi(n/i)*power(n,i-1))%mod;//這里兩個power為什么要-1?由于要%mod,所以求值的時提早將/G(G=n)給做了 }}printf("%d\n",ans);}return 0; }轉載于:https://www.cnblogs.com/AKCqhzdy/p/7598571.html
總結
以上是生活随笔為你收集整理的poj2154Color polya定理+欧拉函数优化的全部內容,希望文章能夠幫你解決所遇到的問題。