A - Big Number
模拟十进制的除法
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e5+500; int main(){ string s;int b; while(cin>>s>>b){ int a=0; for(int i=0;i<s.size();i++){ a=a*10+s[i]-'0'; a%=b; } cout<<a<<endl; } // system("pause"); return 0; }
B - Largest prime factor
模拟埃氏筛 筛素数的过程,如果遇到素数,那么将他的倍数标记成这个素数的标记号。n logn logn
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e6+500; const int maxn=1e6+500; typedef long long ll; int num[N]; void work(){ memset(num,0,sizeof num); num[1]=0; int tot=1; for(int i=2;i<maxn;i++){ if(!num[i]){ num[i]=tot; for(int j=2;j*i<maxn;j++){ num[j*i]=tot; } tot++; } } } int main(){ work(); int n; while(~scanf("%d",&n)){ printf("%d ",num[n]); } // system("pause"); return 0; }
C - A/B
费马小定理,素数模的x逆元为 x的p-2次方
#include<bits/stdc++.h> using namespace std; const int inf=0x3f3f3f3f; const int N=1e6+500; const int maxn=1e6+500; typedef long long ll; const ll mod=9973; ll quickPower(ll a, ll b,ll m) { //计算a的b次方 ll ans = 1; ll base = a; while (b) { if (b & 1) { ans *= base; ans %= m; } base *= base; base %= m; b >>= 1; //注意是b>>=1 not b>>1 } return ans; } int main(){ int t;cin>>t; while(t--){ ll n,b; cin>>n>>b; n%=mod; ll xb= quickPower(b,mod-2,mod)%mod; cout<<((n*xb)%mod)<<endl; } // system("pause"); return 0; }
E - Bi-shoe and Phi-shoe
对于每一个数,查找一个欧拉函数大于等于他的数。
先一遍线性筛欧拉函数,从小到大扫一遍,对于每一个数的欧拉函数,把每一个小于当前欧拉函数,且未被标记的标记为当前值,保证结果最小。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int N=1e6+5; const int maxn=1e6+5; int num[N],phi[N]; int get_ephi(int n) { int m = int(sqrt(n + 0.5)); int ans = n; for (int i = 2; i <= m; i++) { if (n % i == 0) { ans = ans / i * (i - 1); while (n % i == 0) n /= i; } } if (n > 1) ans = ans / n * (n - 1); return ans; } void phi_table(int n) { for (int i = 2; i <= n; i++) phi[i] = 0; phi[1] = 1; for (int i = 2; i <= n; i++) if (!phi[i]) for (int j = i; j <= n; j += i) { if (!phi[j]) phi[j] = j; phi[j] = phi[j] / i * (i - 1); } } // struct node // { // int key,index; // }a[N]; // bool cmp(node a,node b){ // if(a.key!=b.key)return a.key<b.key; // else return a.index<b.index; // } // int check(int x){ // int l=2,r=maxn-1,ans; // while(l<=r){ // int mid=(l+r)>>1; // if(a[mid].key>=x)ans=mid,r=mid-1; // else l=mid+1; // } // return a[ans].index; // } void work(){ phi_table(maxn-1); memset(num,0,sizeof num); for(int i=2;i<maxn;i++){ int xi=phi[i]; while(!num[xi]){ num[xi--]=i; } } // for(int i=2;i<maxn;i++){ // a[i].key=fx[i];a[i].index=i; // } // sort(a+2,a+maxn,cmp); // for(int i=1;i<maxn;i++){ // int tt=check(i); // num[i]=tt; // } } int main(){ int cas=0; work(); int t;cin>>t; while(t--){ int n;cin>>n; ll sum=0; for(int i=1;i<=n;i++){ int a;cin>>a; sum+=num[a]; } printf("Case %d: %lld Xukha ",++cas,sum); } // system("pause"); return 0; }
F - The Embarrassed Cryptographer
预处理素数,a模拟字符串除法,但取余很耗时间,因此三位相加,然后取余。
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> // #include<algorithm> #include<vector> // #include<bits/stdc++.h> using namespace std; #define pb push_back const int maxn=1e6+10; typedef long long ll; // int prime[maxn]; bool isprime[maxn]; int cnt=0; char s[120]; int check(int x){ int sum=0; int len=strlen(s); for(int i=0;i<len;i+=3){ int tt=0; for(int j=i;j<i+3&&j<len;j++){ sum*=10; tt=tt*10+s[j]-'0'; } sum+=tt; sum%=x; } sum%=x; if(sum==0)return 1; return 0; } int prime[maxn+50]; int visit[maxn+50]; void make_prime(){ memset(visit,0,sizeof visit); memset(prime, 0,sizeof prime); for (int i = 2;i <= maxn; i++) { if (!visit[i]) { prime[++prime[0]] = i; //纪录素数, 这个prime[0] 相当于 cnt,用来计数 } for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) { visit[i*prime[j]] = 1; if (i % prime[j] == 0) { break; } } } } int main(){ make_prime(); int L; while(~scanf("%s %d",s,&L)){ if(s[0]=='0'&&L==0)break; bool flag=1; for(int p=1;prime[p]<L;p++){ if(check(prime[p])){ printf("BAD %d ",prime[p]); flag=0; break; } } if(flag)puts("GOOD"); } // system("pause"); return 0; }
G - Who Gets the Most Candies?
求约数直接预处理,线段树模拟队列删除元素,
应该先-1再取模+1 防止模为0的情况。
#include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<algorithm> #include<vector> // #include<bits/stdc++.h> using namespace std; typedef long long ll; #define pb push_back const int N=5e5+50; int n,m; struct SEG{ int sum[N*50]; void push_up(int rt){ sum[rt]=sum[(rt<<1)]+sum[rt<<1 | 1]; } #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1 | 1 void build(int l,int r,int rt){ if(l==r){ sum[rt]=1; return; } int mid=(l+r)>>1; build(lson); build(rson); push_up(rt); } int update(int pos,int l,int r,int rt){//更新a到b区间和 if(l==r){ sum[rt]=0; return l; } int mid=(r+l)>>1; int res; if(pos<=sum[rt<<1])res=update(pos,lson); else res=update(pos-sum[rt<<1],rson); push_up(rt); return res; } }seg; int F[N]; void init(){ fill(F,F+N,2); F[1]=1; for(int i=2;i+i<N;i++){ for(int j=2*i;j<N;j+=i){ F[j]++; } } } char name[N][100],maxname[100]; int num[N]; int main(){ init(); int n,k; while(~scanf("%d %d",&n,&k)){ seg.build(1,n,1); for(int i=1;i<=n;i++){ scanf("%s %d",name[i],&num[i]); } int maxvalue=0; for(int i=1;i<=n;i++){ int cur=seg.update(k,1,n,1); // cout<<i<<" "<<name[cur]<<endl; if(F[i]>maxvalue){ maxvalue=F[i]; strcpy(maxname,name[cur]); } if(i==n)break; int tot=seg.sum[1]; int tmp=(abs(num[cur]))%tot; if(num[cur]>=0)k=(k-1+tmp-1+tot)%tot+1; else k=(k-tmp-1+tot)%tot+1; // k=k%tot+1; // if(num[cur]>0) k=(k-1+tmp-1)%tot+1; // else k=((k-1-tmp+tot))%tot+1; } printf("%s %d ",maxname,maxvalue); } // system("pause"); return 0; }