链接:戳这里
思路:分别先求出两个正多边形的角度想x,y, 然后就是x*i+y*j==360 n*n枚举i,j就可以了,打的时候hack了几发 数据是 5 10
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f #define MAX 1000100 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int T,n,m; const double eps=1e-8; int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); int x=(n-2)*180/n; int y=(m-2)*180/m; ///printf("%.2f %.2f\n",x,y); int flag=0; for(int i=0;i<=1000;i++){ for(int j=0;j<=1000;j++){ if(i*x+j*y==360){ flag=1; break; } } if(flag) break; } if(flag) cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }<strong> </strong>
思路:前段时间做了一下莫比乌斯反演的题,这道题和bzoj 2820很像 (它是gcd(i,j)=prime素数) ,我的博客也写了这道题 可以去看看
这道题是要求gcd(i,j)=完全平方数
bzoj2820的具体分析:戳这里
我感觉还是在理解吧,直接把求素数倍数的前缀和改成完全平方数的倍数的前缀和就可以了
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<iomanip> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define MAX 10000001+5 #define maxn 1e6+5 ///#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; typedef unsigned long long ull; #define INF (1ll<<60)-1 using namespace std; int mu[MAX],prime[MAX/10+5],vis[MAX],d[MAX/10+5],num; ll g[MAX]; int cnt; void Moblus(){ cnt=0; num=0; mst(vis,0); mu[1]=1; for(int i=2;i<=MAX;i++){ if(!vis[i]){ prime[++cnt]=i; mu[i]=-1; } for(int j=1;j<=cnt;j++){ if(i*prime[j]>MAX) break; vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } for(int i=1;i<=MAX;i++){ int t=(int)sqrt(i*1.0); if(t*t==i) d[++num]=i; } for(int i=1;i<=num;i++){ int p=d[i]; for(int j=1;j*p<=MAX;j++){ g[j*p]+=mu[j]; } } for(int i=1;i<=MAX;i++) g[i]+=g[i-1]; } int main(){ Moblus(); int T,n,m; scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); if(n>m) swap(n,m); ll ans=0; for(int i=1,last=0;i<=n;i=last+1){ last=min((n/(n/i)),(m/(m/i))); ans+=(ll)(g[last]-g[i-1])*(n/i)*(m/i); } printf("%I64d\n",(ll)n*m-ans); } return 0; }