HDU
来源:互联网 发布:淘宝led散热片 编辑:程序博客网 时间:2024/06/03 03:39
题目:有一个A*A的正方形,拆成A*A个1*1的小正方形,然后组成k个B*B的正方形,而且剩下一个小正方形,也就是A*A=K*B*B+1。问中间的小正方形连到K个B*B正方形的形状有多少种,有C种颜色,旋转视为等价。
思路:A*A-1=(A-1)*(A+1),把A-1的质因子求出来,把A+1的质因子求出来,合并,然后枚举B,求出C种颜色下B的等价类的数目,然后把其当成颜色去染K个B的项链,中间还有个1。这道题要充分运用质因子来优化。
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")#include<iostream>#include<algorithm>#include<ctime>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<map>#include<set>#include<queue>#include<stack>#include<list>#include<numeric>using namespace std;#define LL long long#define ULL unsigned long long#define INF 0x3f3f3f3f3f3f3f3f#define mm(a,b) memset(a,b,sizeof(a))#define PP puts("*********************");template<class T> T f_abs(T a){ return a > 0 ? a : -a; }template<class T> T gcd(T a, T b){ return b ? gcd(b, a%b) : a; }template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}// 0x3f3f3f3f3f3f3f3fconst LL MOD=1000000007;const int maxn=4e4+50;bool isprime[maxn];int prime[maxn],tol;vector<LL> pri;LL fac[maxn][2],total;LL Inv4,Invk;LL A,C;void make_prime(int n){ for(int i=0;i<=n;i++) isprime[i]=true; isprime[0]=isprime[1]=false; tol=0; for(int i=2;i<=n;i++){ if(isprime[i]) prime[tol++]=i; for(int j=0;j<tol;j++){ if(i*prime[j]<=n) isprime[i*prime[j]]=false; else break; if(i%prime[j]==0) break; } }}LL pow_mod(LL a,LL b){ LL res=1; a=a%MOD; while(b){ if(b&1) res=res*a%MOD; a=a*a%MOD; b/=2; } return res;}LL get_pri(LL n){ for(int i=0;i<tol&&(LL)prime[i]*prime[i]<=n;i++){ if(n%prime[i]==0){ while(n%prime[i]==0){ n/=prime[i]; pri.push_back(prime[i]); } } } if(n>1) pri.push_back(n);}LL get_merge(){ sort(pri.begin(),pri.end()); total=0; fac[total][0]=pri[0]; fac[total++][1]=1; for(int i=1;i<pri.size();i++){ if(pri[i]==fac[total-1][0]) fac[total-1][1]++; else{ fac[total][0]=pri[i]; fac[total++][1]=1; } }}LL Phi(LL n){ LL res=1; for(int i=0;i<total&&fac[i][0]*fac[i][0]<=n;i++){ if(n%fac[i][0]==0){ n/=fac[i][0]; res=res*(fac[i][0]-1); while(n%fac[i][0]==0){ n/=fac[i][0]; res=res*fac[i][0]; } } } if(n>1) res=res*(n-1); return res%MOD;}LL resA;void dfs_A(int i,LL num,LL col,LL K){ if(i==total){ resA=(resA+pow_mod(col,K/num)*Phi(num)%MOD)%MOD; return; } for(int j=0;j<=fac[i][1];j++){//搜索K的因子 dfs_A(i+1,num,col,K); num=num*fac[i][0]; }}LL get_A(LL col,LL K){ resA=0; Invk=pow_mod(K,MOD-2); dfs_A(0,1,col,K); return resA*Invk%MOD*C%MOD;}LL get_B(LL B){ LL ans=pow_mod(C,B*B); ans=(ans+(LL)2*pow_mod(C,(B*B+3)/4)%MOD)%MOD; ans=(ans+pow_mod(C,(B*B+1)/2)%MOD)%MOD; return ans*Inv4%MOD;}LL ans;void dfs_B(int i,LL num){ if(i==total){ LL col=get_B(num); LL K=(A*A-1)/num/num; ans=(ans+get_A(col,K))%MOD; return; } LL tmp=fac[i][1]; for(int j=0;j<=tmp;j+=2,fac[i][1]-=2){ dfs_B(i+1,num); num=num*fac[i][0]; } fac[i][1]=tmp;}int main(){ int T,cas=0; make_prime(maxn-50); Inv4=pow_mod((LL)4,MOD-2); scanf("%d",&T); while(T--){ scanf("%lld%lld",&A,&C); if(A==1){ printf("Case %d: %lld\n",++cas,C); continue; } ans=0; pri.clear(); get_pri(A-1); get_pri(A+1); get_merge();// PP;// for(int i=0;i<total;i++)// printf("%lld %lld\n",fac[i][0],fac[i][1]);// PP; dfs_B(0,1); printf("Case %d: %lld\n",++cas,ans); } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- QT5.9 在线程中导出EXCLE报 CoCreateInstance failure (尚未调用 CoInitialize) 解决办法
- CFGym 101002C 状压DP
- oracle内置函数
- python之Flask(一)
- 【LeetCode】572. Subtree of Another Tree
- HDU
- 【腾讯笔试】满二叉排序树中查找三个节点的最小子树的根节点
- linux命令-sed命令使用(1)
- python中mysql基本操作
- MongoDB C++开发环境搭建
- 分布式消息系统:Kafka
- 使用Maven运行Java main的3种方式
- 数据控制、定义、操作
- leetcode : subtree of another tree