10.11的一些题
T1 loj 2589 Hankson的趣味题
题目大意:
给 a1 a2 b1 b2
求有多少个n满足 gcd(a1,n)=a2 lcm(b1,n)=b2
思路:
枚举b2的所有因数x
判断的时候判断x/a2与a1/a2是否互质 b2/x与b2/b1是否互质
只有都满足的时候才满足 正确性显然
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 1200 12 #define MOD 1000000000 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int T,a1,b1,a2,b2,ans,i; 22 inline int gcd(int a,int b) {return !b?a:gcd(b,a%b);} 23 inline int solve(int x) {if(x%a2) return 0;return gcd(x/a2,a1/a2)==1&&gcd(b2/x,b2/b1)==1;} 24 int main() 25 { 26 T=read(); 27 while(T--) 28 { 29 a1=read(),a2=read(),b1=read(),b2=read(),ans=0; 30 for(i=1;i*i<=b2;i++) 31 if(b2%i==0) ans+=solve(i)+solve(b2/i); 32 if((i-1)*(i-1)==b2) ans-=solve(i-1); 33 printf("%d\n",ans); 34 } 35 }
T2 bzoj 1876 SuperGCD
题目大意:
10000位高精度数求gcd
思路:
使用更相减损术+高精度
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 1200 12 #define MOD 1000000000 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 struct bign 22 { 23 int len,val[MAXN]; 24 bign() {memset(val,0,sizeof(val));len=0;} 25 void Print() 26 { 27 printf("%d",val[len]); 28 for(int i=len-1;i>=0;i--) 29 printf("%09d",val[i]); 30 } 31 bign operator + (const bign &a) const 32 { 33 bign ans; 34 ans.len=max(len,a.len); 35 for(int i=0;i<=ans.len;i++) 36 { 37 ans.val[i]+=val[i]+a.val[i]; 38 if(ans.val[i]>=MOD) {ans.val[i+1]++;ans.val[i]-=MOD;} 39 } 40 if(ans.val[ans.len+1]) ans.len++; 41 return ans; 42 } 43 bign operator - (const bign &a) const 44 { 45 bign ans; 46 ans.len=max(len,a.len); 47 for(int i=0;i<=ans.len;i++) 48 { 49 ans.val[i]+=val[i]-a.val[i]; 50 if(ans.val[i]<0) {ans.val[i+1]--;ans.val[i]+=MOD;} 51 } 52 while(ans.val[ans.len]<=0&&ans.len) ans.len--; 53 return ans; 54 } 55 bool operator < (const bign &a) const 56 { 57 if(len!=a.len) return len<a.len; 58 for(int i=len;i>=0;i--) 59 if(val[i]!=a.val[i]) return val[i]<a.val[i]; 60 } 61 bool operator == (const bign &a) const 62 { 63 if(len!=a.len) return 0; 64 for(int i=len;i>=0;i--) 65 if(val[i]!=a.val[i]) return 0; 66 return 1; 67 } 68 }a,b; 69 int n,m,cnt; 70 char s1[10010],s2[10010]; 71 inline bign div2(bign &x) 72 { 73 bign ans=x;int t; 74 if(ans.val[ans.len]==1&&ans.len) ans.val[ans.len]=0,ans.val[--ans.len]+=MOD; 75 else if(!ans.val[ans.len]) --ans.len; 76 for(int i=ans.len;i>=0;i--) 77 { 78 if((ans.val[i]&1)&&i) ans.val[i-1]+=MOD; 79 ans.val[i]>>=1; 80 } 81 //ans.Print(); 82 //puts(""); 83 return ans; 84 } 85 int main() 86 { 87 //freopen("gcd5.in","r",stdin); 88 scanf("%s%s",s1+1,s2+1); 89 n=strlen(s1+1),m=strlen(s2+1); 90 for(int i=n,pw=1;i;i--) 91 { 92 if(pw==MOD) a.len++,pw=1; 93 a.val[a.len]+=(s1[i]-'0')*pw,pw*=10; 94 } 95 for(int i=m,pw=1;i;i--) 96 { 97 if(pw==MOD) b.len++,pw=1; 98 b.val[b.len]+=(s2[i]-'0')*pw,pw*=10; 99 } 100 //a.Print();puts("");b.Print();puts(""); 101 while((a.val[0]%2==0)&&(b.val[0]%2==0)) a=div2(a),b=div2(b),cnt++; 102 while(a.val[0]%2==0) a=div2(a);while(b.val[0]%2==0) b=div2(b); 103 while(!(a==b)) 104 { 105 //a.Print();puts("");b.Print();puts(""); 106 if(a<b) b=b-a;else a=a-b; 107 while(a.val[0]%2==0) a=div2(a);while(b.val[0]%2==0) b=div2(b); 108 } 109 while(cnt--) a=a+a;a.Print(); 110 }
T3 poj 3421 X-factor chain
题目大意:
给定x 求x的因子组成的满足任意前一项都能整除后一项的序列的最大长度以及最大长度的方案数
思路:
很容易发现最长的序列每一项相当于前一项乘以一个质因子
所以分解质因数可以求出长度 方案数为长度的阶乘/各个质因子的指数的阶乘
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 1200 12 #define MOD 1000000000 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 ll n,ans,k,res,c[35]; 22 int main() 23 { 24 for(int i=c[0]=1;i<=30;i++) c[i]=c[i-1]*i; 25 while(scanf("%lld",&n)!=EOF) 26 { 27 ans=0,k=0,res=1; 28 for(int i=2;i*i<=n;i++) 29 if(n%i==0) 30 { 31 while(n%i==0) {ans++,n/=i,k++;} 32 //cout<<i<<" "<<k<<" "<<n<<endl; 33 res*=c[k],k=0; 34 } 35 if(n>1) ans++; 36 printf("%d %lld\n",ans,c[ans]/res); 37 } 38 }
T4 bzoj 3629 聪明的燕姿
题目大意:
给定S 求有多少个数满足他们的因数之和为S
思路:
对于一个正整数n被分解为p1^a1*p2^a2*...*pk^ak其约数和为(1+p1+p1^2+...+p1^a1)*(1+p2+p2^2+...+p2^a2)*...*(1+pk+pk^2+...+pk^ak)
因此筛出素数后 我们可以搜索 i t s 表示搜到了第i个质数 要求的数乘到了t S被除到了s
当s为1时 t即为所求
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,t,ntp[MAXN+100],p[MAXN+100],tot; 21 int a[MAXN]; 22 void mem() 23 { 24 ntp[0]=ntp[1]=1; 25 for(int i=2;i<=MAXN;i++) 26 { 27 if(!ntp[i]) p[++tot]=i; 28 for(int j=1;i*p[j]<=MAXN;j++) 29 { 30 ntp[i*p[j]]=1; 31 if(i%p[j]==0) break; 32 } 33 } 34 } 35 int cheque(int x) 36 { 37 if(x<MAXN) return !ntp[x]; 38 for(int i=1;p[i]*p[i]<=x;i++) if(x%p[i]==0) return 0; 39 return 1; 40 } 41 42 void dfs(int i,int u,int v) 43 { 44 //cout<<i<<" "<<u<<" "<<v<<" "<<t<<endl; 45 if(v==1) a[++t]=u; 46 else 47 { 48 if(v-1>p[i]&&cheque(v-1)) a[++t]=u*(v-1); 49 //cout<<cheque(v-1)<<endl; 50 for(int j=i+1;p[j]*p[j]<=v;j++) 51 for(int t=p[j],s=t+1;s<=v;t*=p[j],s+=t) 52 if(v%s==0) dfs(j,u*t,v/s); 53 } 54 } 55 int main() 56 { 57 mem(); 58 while(scanf("%d",&n)!=EOF) 59 { 60 t=0;dfs(0,1,n); 61 printf("%d\n",t);sort(a+1,a+t+1); 62 for(int i=1;i<=t;i++) {if(i<t)printf("%d ",a[i]);else printf("%d\n",a[t]);} 63 } 64 }