文章目录
- [HDU 5512](http://acm.hdu.edu.cn/showproblem.php?pid=5512)
- [pku2115(important)](http://poj.org/problem?id=2115)
- [pku2891(excrt模板)](http://poj.org/problem?id=2891)
- [pku1006](http://poj.org/problem?id=1006)
- [HDU 5768 Lucky7 数论(含crt模板)](http://acm.hdu.edu.cn/showproblem.php?pid=5768)
- [HDU 1573 X问题(excrt模板)](http://acm.hdu.edu.cn/showproblem.php?pid=1573)
- [pku2142](http://poj.org/problem?id=2142)
- [HDU 4675 GCD of Sequence (2013多校7 1010题数学题)](http://acm.hdu.edu.cn/showproblem.php?pid=4675)
- [HDU 4655 Cut Pieces(2013多校6 1001题简单数学题)](http://acm.hdu.edu.cn/showproblem.php?pid=4655)
HDU 5512
/*根据gcd(a,b)=gcd(a,a-b)可知,gcd(a,b)一定在最后的集合中 设d=gcd(a,b),则小于等于n的所有d的倍数均可以得到, 且不为d的倍数的均得不到*/
#include<bits/stdc++.h>
using namespace std;
int T,a,b,n,i,ans;
int main(){
scanf("%d",&T);
for (i=1;i<=T;i++){
scanf("%d%d%d",&n,&a,&b);
ans=n/__gcd(a,b);
printf("Case #%d: %s\n",i,ans&1?"Yuwgna":"Iaka");
}
}
pku2115(important)
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a,b,c,k,t,x,y;
ll ex_gcd(ll a,ll b,ll &x,ll &y){
if (!b){
x=1,y=0;
return a;
}
ll t=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return t;
}
int main(){
while (~scanf("%lld%lld%lld%lld",&a,&b,&c,&k)){
if (!a && !b && !c && !k) return 0;
k=1ll<<k;
if ((b-a)%__gcd(c,k)!=0) puts("FOREVER");
else{
t=ex_gcd(c,k,x,y);
x=x*((b-a)/t)%k;
x=(x%(k/t)+k/t)%(k/t);//很重要
printf("%lld\n",x);
}
}
}
pku2891(excrt模板)
#include<cstdio>
using namespace std;
typedef long long ll;
int n,i,fl;
ll n1,a1,n2,a2,c,gcd,x,y,t;
ll ex_gcd(ll a,ll b,ll &x,ll &y){
if (!b){
x=1,y=0;
return a;
}
ll t=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return t;
}
int main(){
while (~scanf("%d",&n)){
scanf("%lld%lld",&n1,&a1);
fl=0;
for (i=1;i<n;i++){
scanf("%lld%lld",&n2,&a2);
if (fl) continue;
c=a2-a1;
gcd=ex_gcd(n1,n2,x,y);
if (c%gcd){
fl=1;puts("-1");
continue;
}
x*=c/gcd;
t=n2/gcd;
x=(x%t+t)%t;
a1+=x*n1;
n1*=n2/gcd;
}
if (!fl) printf("%lld\n",a1);
}
}
pku1006
//crt
#include<cstdio>
using namespace std;
int p,e,i,d,ca,n;
int main(){
while(~scanf("%d%d%d%d",&p,&e,&i,&d) && p!=-1){
n=(5544*p+14421*e+1288*i-d+21252-1)%21252+1;
printf("Case %d: the next triple peak occurs in %d days.\n",++ca,n);
}
}
HDU 5768 Lucky7 数论(含crt模板)
//https://blog.csdn.net/danliwoo/article/details/52058069
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x,y,ans,l,r;
int n,m[16],a[16],s[16],cnt,tmp,i,T,j,ca;
ll mul(ll x,ll y,ll z){
ll res=0;
while (y){
if (y&1) (res+=x)%=z;
(x+=x)%=z;y>>=1;
}
return res;
}
ll calc(ll x,ll y,ll M){
return (x-y)/M;
}
void ex_gcd(ll a,ll b,ll &x,ll &y){
if (!b) x=1,y=0;
else ex_gcd(b,a%b,y,x),y-=a/b*x;
}
ll crt(ll l,ll r){
ll M=1,sum=0;
for (int i=0;i<=n;i++)
if (s[i]) M*=m[i];
for (int i=0;i<=n;i++)
if (s[i]){
ll t=M/m[i];
ex_gcd(t,m[i],x,y);
x=(x%m[i]+m[i])%m[i];
sum=(sum+mul(a[i]*t%M,x,M)%M+M)%M;
}
return calc(r+M,sum,M)-calc(l-1+M,sum,M);
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%lld%lld",&n,&l,&r);
ans=0;
m[n]=7;a[n]=0;s[n]=1;
for (i=0;i<n;i++) scanf("%d%d",&m[i],&a[i]);
for (i=0;i<1<<n;i++){
tmp=i;cnt=0;
for (j=0;j<n;j++) s[j]=tmp&1,cnt^=s[j],tmp>>=1;
ans+=crt(l,r)*(cnt==0?1:-1);
}
printf("Case #%d: %lld\n",++ca,ans);
}
}
HDU 1573 X问题(excrt模板)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T,i,n,m,fl,a[11],b[11];
ll a1,a2,c,n1,n2,x,y,gcd,t;
ll ex_gcd(ll a,ll b,ll &x,ll &y){
if (!b){x=1,y=0;return a;}
ll r=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return r;
}
int main(){
scanf("%d",&T);
while (T--){
scanf("%d%d",&n,&m);fl=0;
for (i=0;i<m;i++) scanf("%d",&a[i]);
for (i=0;i<m;i++) scanf("%d",&b[i]);
n1=a[0];a1=b[0];
for (i=1;i<m;i++){
n2=a[i];a2=b[i];
gcd=ex_gcd(n1,n2,x,y);
c=a2-a1;
if (c%gcd){
fl=1;break;
}
x*=c/gcd;
t=n2/gcd;
x=(x%t+t)%t;
a1+=n1*x;
n1*=n2/gcd;
}
if (!a1){//特判
a1=1;
for (i=0;i<m;i++) a1*=a[i]/__gcd(a1,(ll)a[i]);
n1=a1;
}
printf("%lld\n",fl || n<a1?0:(n-a1)/n1+1);
}
}
pku2142
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int a,b,c,r,x,y,vx,vy;
int ex_gcd(int a,int b,int &x,int &y){
if (!b){x=1;y=0;return a;}
int r=ex_gcd(b,a%b,y,x);
y-=a/b*x;
return r;
}
int main(){
while (~scanf("%d%d%d",&a,&b,&c) && a){
r=ex_gcd(a,b,x,y);
a/=r;b/=r;c/=r;
vx=(x*c%b+b)%b;
vy=abs((c-a*vx)/b);
y=(y*c%a+a)%a;
x=abs((c-b*y)/a);
if (x+y>vx+vy) x=vx,y=vy;
printf("%d %d\n",x,y);
}
}
HDU 4675 GCD of Sequence (2013多校7 1010题数学题)
题意:有n个数,每个数的小于等于M(M <=10^5),现在让你求把原数列改变k个数,使新数列最大公约数为d (d为1~M)的方法数,分别输出
思路:当最大公约数为d时,易得1~M中d的倍数有 M/d个,我们统计原数列中d的倍数的个数cnt,那么所先要将原数列中的非d得倍数的数变成d的倍数,这样的方案数一共有 (M/d)n−cnt 然后还剩下 k−(n−cnt)个数需要变换,那么方案数为 Ccntn−k∗(M/d−1)k−(n−cnt) 那么总的为d的倍数的方案数为 (M/d)n−cnt∗Ccntn−k∗(M/d−1)k−(n−cnt)此时,还需要减掉为id的倍数的方案数(因为最终答案要求的是最大公约数为d的方案数,而此时的算的是为d的倍数的方案数)这时候先算好组合数,(因为组合数的第二个数是不变的,复杂度从M降为1)并统计好1~M每个数出现的次数(复杂度从n降为lgm),从m开始计算答案,这样复杂度为mlgm。
//https://blog.csdn.net/mowayao/article/details/38440655
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=300002,M=1e9+7;
int n,tmp,k,i,sum,t,d,m,j;
ll C[N],ans[N],cnt[N],x,y;
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline int read(){
int x=0,fl=1;char ch=gc();
for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
inline void wri(int a){if(a<0)a=-a,putchar('-');if(a>=10)wri(a/10);putchar(a%10|48);}
void ex_gcd(ll a,ll b,ll &x,ll &y){
if (!b) x=1,y=0;
else ex_gcd(b,a%b,y,x),y-=a/b*x;
}
ll inv(ll t){
ex_gcd(t,M,x,y);
return (x%M+M)%M;
}
ll pm(ll x,ll y){
ll z=1;
for (;y;y>>=1,x=x*x%M)
if (y&1) z=z*x%M;
return z;
}
int main(){
while (~scanf("%d",&n)){
m=read();k=read();
tmp=n-k;
C[tmp]=1;
memset(cnt,0,sizeof(cnt));
for (i=tmp+1;i<=n;i++) C[i]=C[i-1]*i%M*inv(i-tmp)%M;
for (i=0;i<n;i++) x=read(),cnt[x]++;
for (i=m;i;i--){
sum=cnt[i];t=0;
for (j=i+i;j<=m;j+=i) sum+=cnt[j],t=(t+ans[j])%M;
if (sum<tmp) ans[i]=0;
else{
d=m/i;
ans[i]=(pm(d,n-sum)*C[sum]%M*pm(d-1,sum-tmp)%M-t+M)%M;
}
}
for (i=1;i<=m;i++) wri(ans[i]),putchar(i==m?'\n':' ');
}
}
HDU 4655 Cut Pieces(2013多校6 1001题简单数学题)
/*https://blog.csdn.net/solotzg/article/details/25082233 if a[i-1] < a[i] then dp[i] = (dp[i-1]*a[i]) + a[0]*a[1]*....a[i-1]*(a[i] - 1); else dp[i] = (dp[i-1]*a[i]) + a[0]*a[1]*....a[i-2]*(a[i-1]-1)*a[i]; 可以手模理解一下 */
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e9+7,N=1e6+2;
int b[N],T,i,j,n;
ll a[N],dp[N],s1,s2;
int main(){
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (i=0;i<n;i++) scanf("%d",&b[i]);
sort(b,b+n);
for (i=0,j=0;j<n;i++,j+=2) a[j]=b[i];
for (i=n-1,j=1;j<n;i--,j+=2) a[j]=b[i];
dp[0]=a[0];s1=a[0];s2=1;
for (i=1;i<n;i++){
if (a[i-1]<a[i]) dp[i]=(dp[i-1]*a[i]%M+s1*(a[i]-1)%M)%M;
else dp[i]=(dp[i-1]*a[i]%M+s2*(a[i-1]-1)%M*a[i]%M)%M;
s2=s1;
s1=s1*a[i]%M;
}
printf("%d\n",dp[n-1]);
}
}