关于最大公约数的疑惑
题目描述
小光是个十分喜欢素数的人,有一天他在学习最大公约数的时候突然想到了一个问题,他想知道从1到n这n个整数中有多少对最大公约数为素数的(x,y),即有多少(x,y),gcd(x,y)=素数,1<=x,y<=n。但是小光刚刚接触最大公约数,不能解决这个问题,于是他希望你能帮助他解决这个问题。
输入
多组测试数据,对于每组数据:
每行为一个整数N (1<=N<=10^5)
输出
对于每组数据:
每行输出 (x,y)的个数
样例输入
5
样例输出
5
直接筛法求素数+欧拉函数。在筛法求素数的时候顺便给每个数*(1-1/pi)其中pi为该数的质因子。
然后嘛 这题有点坑 他说的数对竟然是包括相同两个数的数对 以及例如(2,4)及(4,2)这样顺序不同的数对算作两个数对。。。所以我刚打的时候好几遍都不能AC...
贴代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #define clr(x) memset(x,0,sizeof(x)) 5 using namespace std; 6 7 int a[100001]; 8 int ct[100001]; 9 int pr[100001]; 10 void prime(int n); 11 int main() 12 { 13 int n,m,i,j,sum; 14 prime(100000); 15 while(scanf("%d",&n)==1) 16 { 17 sum=0; 18 for(i=1;pr[i]<=n;i++) 19 { 20 j=n/pr[i]; 21 sum+=ct[j]; 22 } 23 printf("%d\n",sum*2+i-1); 24 } 25 26 } 27 void prime(int n) 28 { 29 clr(a); 30 clr(pr); 31 int num=0; 32 a[0]=a[1]=1; 33 for(int i=1;i<=n;i++) 34 ct[i]=i; 35 ct[1]=0; 36 for(int i=1;i<=n;i++) 37 if(!a[i]) 38 { 39 for(int j=i;j<=n;j+=i) 40 { 41 a[j]=1; 42 ct[j]=ct[j]/i*(i-1); 43 } 44 pr[++num]=i; 45 } 46 for(int i=1;i<=n;i++) 47 ct[i]+=ct[i-1]; 48 pr[0]=num; 49 return ; 50 }
一道简单的几何变换
题目描述
小光最近在学习几何变换,老师给他留了一个作业,在二维平面上有n个点(x,y),老师给了m个几何变换对n个点进行操作,要求小光输出变换后的n个点的坐标(x’,y’)。小光为了偷懒,请求你帮他写个程序来完成老师的作业。
由于小光刚刚学习几何变换,老师只会给出四种变换,如下:
平移变换: (x’,y’)=(x+p,y’+q) 程序的输入格式为:1 p q (p,q为整数)
缩放变换: (x’,y’)=(x*L,y*L) 程序的输入格式为:2 L (L为整数)
上下翻转: (x’,y’)=(x,-y) 程序的输入格式为:3
左右翻转: (x’,y’)=(-x,y) 程序的输入格式为:4
输入
多组测试数据,对于每组数据:
第一行为N(1<=N<=10^5)
然后以下N行,N个点(x,y) 其中x,y均为整数
然后一行为M (1<=M<=10^5)
然后以下M行,M个变换,输入格式如上所述。
输出
对于每组数据:
输出N行,每行为变换点坐标。
样例输入
2 1 1 2 2 1 1 1 1
样例输出
2 2 3 3
这题也没什么好说的。。其实算不上数论,只是顶着变换的名头= =。然后呢一看数据量如果分别一个一个处理一定会超时。于是就想到了把所有的处理化为一次处理。
然后呢 用ct 代表全部处理过后是否翻转变换 =1为没翻转,=-1为翻转了。两次翻转相当于没翻转。每次翻转后ct=-ct。
用l表示全部处理过后的缩放倍数。
然后平移变换和翻转以及缩放相关,处理比较麻烦,用acum存最后处理完平移的多少。每次平移变换为acum=+a*ct。每次缩放时acum=*t,t为每次缩放变换的大小
对于每个数a[i]处理完后为a[i].x=a[i].x*l*ctx+acumx*ctx; a[i].y=a[i].y*l*cty+acumy*cty;
代码处理如下:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 struct pos{ 5 int x,y; 6 }a[100001]; 7 int main() 8 { 9 int ctx,cty,acumx,acumy; 10 int n,m,k,l,t,p,q; 11 while(scanf("%d",&n)==1) 12 { 13 for(int i=1;i<=n;i++) 14 scanf("%d%d",&a[i].x,&a[i].y); 15 scanf("%d",&m); 16 ctx=cty=l=1; 17 acumx=acumy=0; 18 for(int i=1;i<=m;i++) 19 { 20 scanf("%d",&k); 21 if(k==1) 22 { 23 scanf("%d%d",&p,&q); 24 acumx+=ctx*p; 25 acumy+=cty*q; 26 } 27 if(k==2) 28 { 29 scanf("%d",&t); 30 l*=t; 31 acumx*=t; 32 acumy*=t; 33 } 34 if(k==3) 35 cty=-cty; 36 if(k==4) 37 ctx=-ctx; 38 } 39 for(int i=1;i<=n;i++) 40 { 41 a[i].x=a[i].x*l*ctx+acumx*ctx; 42 a[i].y=a[i].y*l*cty+acumy*cty; 43 printf("%d %d\n",a[i].x,a[i].y); 44 } 45 } 46 return 0; 47 }