今天做JSOI2012的题。
才120,其实是可以拿很多部分分什么的,但是都打错。。。
(代码实现能力太差了。
1、
4330: JSOI2012 爱之项链
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 50 Solved: 24Description
在进香河,流传着这样一段美丽的故事。zyg与kzn是两个生活在进香河的孩子,一天,他们两人闹矛盾了,于是zyg送给了kzn一条精美的爱之项链。从此他们幸福生活在一起。这则故事的真实性到今天已经没有意义了,然而我们关注的是那一条精美的爱之项链。这是一条由N个精致的戒指与一块特殊纪念品相连而成的环形,如下图中的爱心符号正是一种特殊纪念品。(据说是2012年情人节时zyg特意托人订制的)上面的每一枚戒指又是由M个带磁性的特殊彩色球状物组成的环形。也许你会认为,这所谓的戒指,更像是一条条小项链。下图给出了一种可行的方案,其中左边描述的是单一的一枚戒指,右图描述的是项链。这里,所有带磁性的特殊彩色球状物的颜色只有R种,这里我们用1到R来表示。如果一枚戒指可以通过顺时针或逆时针的旋转后与另外一枚戒指相同,则认为这是两枚相同的戒指。对于一条爱之项链,要求满足任何相邻两枚戒指必须是不相同的。同时,特殊纪念品左右两枚戒指也必须是不同的。现在给定N,M和R,问究竟有多少种不同的爱之项链。注意:1、特殊纪念品的插入位置不同,也许会得到不同的爱之项链。2、这里我们只考虑旋转后是否相同,不考虑翻转操作,这一点不论是对于每一枚戒指,还是对于整条项链,都是这样的。Input
一行,三个正整数,分别是N,M和R。Output
一行,表示有多少种不同的爱之项链。你只需要将答案模3214567。Sample Input
10 5 4Sample Output
1398595HINT
对于100%的数据,N<=10^15,M<=10^9,R<=10^6。
应上传者要求,此题不公开,如有异议,请提出.
Source
挺裸的置换的。
首先算戒指有多少种
$\sum_{i=1}^{m} R^{gcd(i,m)}$
$=\sum_{d|n}R^d*\varphi(d)$
不动点方案数记得最后除以m!!!!
考场上竟然觉得要杜教筛才能过,但是不会,就直接用第一条式子打80分的,后面那个也是没有矩乘了,【然而还是没用LL搞到没什么分哭死。。
其实枚举n的约数就好了,不会超过$\sqrt{n}$个。
然后串项链,可以把环断成链,要求相邻的不同且首尾不同
$f[i]$表示串$i$个首尾不一定不相同的方案
$dp[i]$表示串$i$个首尾不同的方案【都要满足相邻的不同】
假设第一步算到有c种戒指
$f[i]=f[i-1]*(c-1)$
$dp[i]=dp[i-1]*(c-2)+(f[i-1]-dp[i-1])*(c-1)=f[i]-dp[i-1]$
这样子的递推式显然可以用矩阵加速。
还有一个问题是mod挺小的,若m为mod的倍数,就没有逆元,就不能除了。
小山羊说的先模mod^2搞搞??不知道。。数据没有。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define Maxn 10000010 8 #define Maxm 1000010 9 #define LL long long 10 const int Mod=3214567; 11 12 int pw[Maxm],f[Maxn],dp[Maxn]; 13 14 int gcd(int a,int b) 15 { 16 if(b==0) return a; 17 return gcd(b,a%b); 18 } 19 20 int qpow(int x,int b) 21 { 22 int ans=1; 23 while(b) 24 { 25 if(b&1) ans=1LL*ans*x%Mod; 26 x=1LL*x*x%Mod; 27 b>>=1; 28 } 29 return ans; 30 } 31 32 LL n; 33 int m,r; 34 int a1,pl=0,pr[Maxm],rr[Maxm]; 35 36 void ffind(int x,int dd,int phi) 37 { 38 if(x==pl+1) 39 { 40 a1=(a1+1LL*qpow(r,m/dd)*phi)%Mod; 41 return; 42 } 43 ffind(x+1,dd,phi); 44 int nw=1; 45 for(int i=1;i<=rr[x];i++) 46 { 47 ffind(x+1,dd*nw*pr[x],phi*(pr[x]-1)*nw); 48 nw*=pr[x]; 49 } 50 } 51 52 struct node 53 { 54 int w[4][4]; 55 }t[5]; 56 57 void mul(int x,int y,int z) 58 { 59 t[3].w[1][1]=t[3].w[1][2]=t[3].w[2][1]=t[3].w[2][2]=0; 60 for(int k=1;k<=2;k++) 61 for(int i=1;i<=2;i++) 62 for(int j=1;j<=2;j++) 63 t[3].w[i][j]=(t[3].w[i][j]+1LL*t[y].w[i][k]*t[z].w[k][j]%Mod)%Mod; 64 for(int i=1;i<=2;i++) for(int j=1;j<=2;j++) t[x].w[i][j]=t[3].w[i][j]; 65 } 66 67 void qpw(LL b) 68 { 69 t[1].w[1][1]=1;t[1].w[1][2]=0; 70 t[1].w[2][1]=0;t[1].w[2][2]=1; 71 while(b) 72 { 73 if(b&1) mul(1,0,1); 74 mul(0,0,0); 75 b>>=1; 76 } 77 } 78 79 int main() 80 { 81 scanf("%lld%d%d",&n,&m,&r); 82 // pw[0]=1; 83 // for(int i=1;i<=m;i++) pw[i]=1LL*r*pw[i-1]%Mod; 84 85 int mm=m; 86 for(int i=2;i*i<=mm;i++) if(mm%i==0) 87 { 88 pr[++pl]=i;rr[pl]=0; 89 while(mm%i==0) rr[pl]++,mm/=i; 90 } 91 if(mm) pr[++pl]=mm,rr[pl]=1; 92 a1=0; 93 ffind(1,1,1); 94 a1=1LL*a1*qpow(m,Mod-2)%Mod; 95 96 t[0].w[1][1]=a1-1;t[0].w[1][2]=0; 97 t[0].w[2][1]=a1-1;t[0].w[2][2]=-1; 98 99 qpw(n-1); 100 int ans=(1LL*t[1].w[2][1]*a1)%Mod; 101 printf("%d\n",(ans%Mod+Mod)%Mod); 102 103 return 0; 104 }