SGU 294 He's Circles (polay计数)
生活随笔
收集整理的這篇文章主要介紹了
SGU 294 He's Circles (polay计数)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.sgu.ru/problem.php?contest=0&problem=294
題意:一個項鏈有n個珠子,每個珠子為黑色或白色。問有多少種不同的項鏈?
思路:基本的polay計數,只不過數比較大,除了高精度外一個優化在于,不是依次計算Gcd(n,i)(1<=i<=n),而是直接枚舉L=n/i,這樣求出L的歐拉函數K,則答案為sigama(2^i*K)/n。
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <set> #include <stack> #include <string> #include <map>#define max(x,y) ((x)>(y)?(x):(y)) #define min(x,y) ((x)<(y)?(x):(y)) #define abs(x) ((x)>=0?(x):-(x)) #define i64 long long #define u32 unsigned int #define u64 unsigned long long #define clr(x,y) memset(x,y,sizeof(x)) #define CLR(x) x.clear() #define ph(x) push(x) #define pb(x) push_back(x) #define Len(x) x.length() #define SZ(x) x.size() #define PI acos(-1.0) #define sqr(x) ((x)*(x))#define FOR0(i,x) for(i=0;i<x;i++) #define FOR1(i,x) for(i=1;i<=x;i++) #define FOR(i,a,b) for(i=a;i<=b;i++) #define DOW0(i,x) for(i=x;i>=0;i--) #define DOW1(i,x) for(i=x;i>=1;i--) #define DOW(i,a,b) for(i=a;i>=b;i--) using namespace std;void RD(int &x){scanf("%d",&x);} void RD(i64 &x){scanf("%lld",&x);} void RD(u32 &x){scanf("%u",&x);} void RD(u64 &x){scanf("%llu",&x);} void RD(double &x){scanf("%lf",&x);} void RD(int &x,int &y){scanf("%d%d",&x,&y);} void RD(i64 &x,i64 &y){scanf("%lld%lld",&x,&y);} void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);} void RD(double &x,double &y){scanf("%lf%lf",&x,&y);} void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);} void RD(i64 &x,i64 &y,i64 &z){scanf("%I64d%I64d%I64d",&x,&y,&z);} void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);} void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);} void RD(char &x){x=getchar();} void RD(char *s){scanf("%s",s);} void RD(string &s){cin>>s;}void PR(int x) {printf("%d\n",x);} void PR(i64 x) {printf("%lld\n",x);} void PR(u32 x) {printf("%u\n",x);} void PR(double x) {printf("%.4lf\n",x);} void PR(char x) {printf("%c\n",x);} void PR(char *x) {printf("%s\n",x);} void PR(string x) {cout<<x<<endl;}const i64 MOD=10000000;class BigNum{public:i64 a[10000];public:BigNum operator+(BigNum temp){BigNum ans;i64 i,j,k,p;if(a[0]>temp.a[0]) p=a[0];else p=temp.a[0];for(i=a[0],j=temp.a[0],k=p;j>=1&&i>=1;i--,j--,k--)ans.a[k]=a[i]+temp.a[j];if(j==0){while(i>=1) ans.a[i]=a[i--];}else{while(j>=1) ans.a[j]=temp.a[j--];}ans.a[0]=0;for(i=p;i>=1;i--){ans.a[i-1]+=ans.a[i]/MOD;ans.a[i]%=MOD;}if(ans.a[0]){for(i=p+1;i>=1;i--) ans.a[i]=ans.a[i-1];ans.a[0]=p+1;}else ans.a[0]=p;return ans;}BigNum operator-(BigNum temp){BigNum ans;int i,j;for(i=0;i<=a[0];i++) ans.a[i]=a[i];for(i=ans.a[0],j=temp.a[0];i>=1&&j>=1;i--,j--)ans.a[i]-=temp.a[j];for(i=ans.a[0];i>=1;i--) if(ans.a[i]<0){ans.a[i]+=MOD;ans.a[i-1]--;}for(i=1;i<=a[0];i++) if(ans.a[i]) break;if(i>a[0]){ans.a[0]=1;ans.a[1]=0;return ans;}for(j=i;j<=a[0];j++) ans.a[j+1-i]=ans.a[j];ans.a[0]=a[0]-i+1;return ans;}BigNum operator*(BigNum temp){BigNum ans;int i,j,p=a[0]+temp.a[0]-1;memset(ans.a,0,sizeof(ans.a));for(i=a[0];i>=1;i--) for(j=temp.a[0];j>=1;j--)ans.a[i+j-1]+=a[i]*temp.a[j];ans.a[0]=0;for(i=p;i>=1;i--){ans.a[i-1]+=ans.a[i]/MOD;ans.a[i]%=MOD;}if(ans.a[0]){for(i=p;i>=0;i--) ans.a[i+1]=ans.a[i];ans.a[0]=p+1;}else ans.a[0]=p;return ans;}BigNum operator*(int temp){BigNum ans;int i;for(i=1;i<=a[0];i++) ans.a[i]=a[i]*temp;ans.a[0]=0;for(i=a[0];i>=1;i--){ans.a[i-1]+=ans.a[i]/MOD;ans.a[i]%=MOD;}if(ans.a[0]){for(i=a[0];i>=0;i--) ans.a[i+1]=ans.a[i];ans.a[0]=a[0]+1;}else ans.a[0]=a[0];if(ans.a[1]>=MOD){for(i=ans.a[0];i>=0;i--) ans.a[i+1]=ans.a[i];ans.a[0]++;}return ans;}BigNum operator/(int x){BigNum ans;int i,j;i64 p;for(i=1;i<=a[0];i++){if(i==1){ans.a[i]=a[i]/x;p=a[i]%x;}else{ans.a[i]=(p*MOD+a[i])/x;p=(p*MOD+a[i])%x;}}for(i=1;i<=a[0];i++) if(ans.a[i]) break;if(i>a[0]){ans.a[0]=1;ans.a[1]=0;return ans;}for(j=i;j<=a[0];j++) ans.a[j+1-i]=ans.a[j];ans.a[0]=a[0]-i+1;return ans;}BigNum operator/(BigNum temp){BigNum ans,t;BigNum low=BigNum(1),high,mid;int i;for(i=1;i<=a[0];i++) t.a[i]=high.a[i]=a[i];t.a[0]=high.a[0]=a[0];while(!(low>high)){mid=(low+high)/2;if(mid*temp>t) high=mid-BigNum(1);else low=mid+BigNum(1);}if(!(low>t)&&!(temp*low>t)) return low;return high;}BigNum operator%(BigNum temp){int i;BigNum t;for(i=1;i<=a[0];i++) t.a[i]=a[i];t.a[0]=a[0];return t-t/temp*temp;}BigNum power(int n){BigNum ans=BigNum(1),temp=*this;while(n){if(n&1) ans=ans*temp;temp=temp*temp;n>>=1;}return ans;}public:BigNum(){a[0]=1;a[1]=0;}BigNum(int x){if(x>=MOD) a[0]=2,a[1]=x/MOD,a[2]=x%MOD;else a[0]=1,a[1]=x;}BigNum(i64 x){stack<i64> s;while(x){s.push(x%MOD);x/=MOD;}a[0]=s.size();int k=0;while(!s.empty()){a[++k]=s.top();s.pop();}}BigNum(string str){int i;for(i=0;i<str.length();i++) if(str[i]!='0') break;if(i==str.length()){a[0]=1;a[1]=0;return;}str=str.substr(i,str.length()-i);int p=str.length()%7,j;i64 k;a[0]=0;if(p){a[0]=1;k=0;for(i=0;i<p;i++) k=k*10+str[i]-'0';a[1]=k;str=str.substr(p,str.length()-p);}for(i=0;i<str.length();){k=0;for(j=i;j<i+7;j++) k=k*10+str[j]-'0';a[++a[0]]=k;i=j;}}int operator==(BigNum temp){if(a[0]!=temp.a[0]) return 0;for(int i=1;i<=a[0];i++) if(a[i]!=temp.a[i]) return 0;return 1;}int operator>(BigNum temp){if(a[0]>temp.a[0]) return 1;if(a[0]<temp.a[0]) return 0;for(int i=1;i<=a[0];i++) if(a[i]!=temp.a[i]) return a[i]>temp.a[i];return 0;}void print(){int i=1;while(i<=a[0]&&a[i]==0) i++;if(i>a[0]){puts("0");return;}printf("%lld",a[i++]);while(i<=a[0]) printf("%07lld",a[i++]);}};int n; vector<int> V; BigNum ans;int cal(int n) {int i;for(i=0;i<SZ(V)&&V[i]<=n;i++) if(n%V[i]==0) n=n/V[i]*(V[i]-1);return n; }int main() {RD(n);int i,k=n;for(i=2;i*i<=k;i++) if(k%i==0){V.pb(i);while(k%i==0) k/=i;}if(k>1) V.pb(k);for(i=1;i<=n;i++) if(n%i==0){k=cal(n/i);ans=ans+BigNum(2).power(i)*k;}ans=ans/n;ans.print();puts("");return 0; }
總結
以上是生活随笔為你收集整理的SGU 294 He's Circles (polay计数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 优化ASP.NET应用程序性能研究与探讨
- 下一篇: React事件优雅绑定