solved 3
rank 2
A(博弈)
题意:平面上有形成正n边形的n个点,两个人轮流行动,每次可以连接两个点,但不能和之前的线相交,当连成凸多边形时获胜,问先手胜还是后手胜。
(待填)
B
题意:有一棵奇形怪状的树(不好描述。。),求两个顶点路径的点权和。
找找规律乱搞。。
#include <bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/hash_policy.hpp> #include<ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #define pb push_back #define mp make_pair #define st first #define nd second const int N =1e5 + 7 ; ll get(ll x){ ll res=1; while((res-1)*2<x){ res=res*2; } return res-1; } vector<ll> patha,pathb; int main() { ll a,b,ans=0; cin>>a>>b; ll fa=get(a),fb=get(b); ll aa=fa,bb=fb; ll po=(fa+1)/2; while(fa!=a){ patha.pb(fa); if(a>fa)fa=fa+po; else fa=fa-po; po/=2; } patha.pb(a); po=(fb+1)/2; while(fb!=b){ pathb.pb(fb); if(b>fb)fb=fb+po; else fb=fb-po; po/=2; } pathb.pb(b); ll f=-1; int i; for(i=0;i<min(patha.size(),pathb.size());i++){ if(patha[i]==pathb[i]){ f=patha[i]; continue; } ans+=patha[i]+pathb[i]; } if(patha.size()>pathb.size())for(;i<patha.size();i++)ans+=patha[i]; else for(;i<pathb.size();i++)ans+=pathb[i]; if(f!=-1)ans+=f; if(aa>bb)swap(aa,bb); while((aa+1)*2<(bb+1)){ ans+=(aa+1)*2-1; aa=(aa+1)*2-1; } cout<<ans; //for(int i=0;i<patha.size();i++)cout<<patha[i]<<endl; }
01:51(1A)
C
题意:给出每个面含有的顶点个数,每个顶点所在的面的个数,问是否有这样的正多边形,如果有,输出边数、顶点数和面数。
只有4、6、8、12、20五种正多面体,手玩一下打表。
#include <bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/hash_policy.hpp> #include<ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #define pb push_back #define mp make_pair #define st first #define nd second #define gg cout<<-1<<" "<<-1<<" "<<-1<<endl const int N =2e6 + 7 ; int main() { int p,q; while(cin>>p>>q){ if(!p&&!q)break; else if(p==3){ if(q==3)cout<<4<<" "<<6<<" "<<4<<endl; else if(q==4)cout<<6<<" "<<12<<" "<<8<<endl; else if(q==5)cout<<12<<" "<<30<<" "<<20<<endl; else gg; continue; } else if(p==4){ if(q==3)cout<<8<<" "<<12<<" "<<6<<endl; else gg; continue; } else if(p==5){ if(q==3)cout<<20<<" "<<30<<" "<<12<<endl; else gg; continue; } else gg; } }
02:30(1A)
D
题意:一个-1e100到+1e100的坐标轴,有三种移动方式,每种移动方式p(-1e6<p<1e6)代表可以从x走到x+p,可以走无限步,求能到达的点占所有点的比例。
(待填)
E(欧拉函数)
题意:求L-R的欧拉函数和,L<=R<=4e12,R-L<=1e6
先用线性筛筛出2e6之内的素数,然后用这些素数筛这个区间,利用欧拉函数计算公式即可,筛剩下的数一定是素数。
#include <bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/hash_policy.hpp> #include<ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #define pb push_back #define mp make_pair #define st first #define nd second const int N =1e7 + 7 ; int prime[N],notprime[N],cnt; ll a,b; ll re[N],ans[N]; void euler(int n){ notprime[1]=1; for(int i=2;i<=n;i++){ if(!notprime[i]){ prime[++cnt]=i; } for(int j=1;j<=cnt&&prime[j]*i<=n;j++){ notprime[i*prime[j]]=1; if(i%prime[j]==0){ break; } } } } void euler2(ll l,ll r){ for(int i=1;i<=cnt;i++){ for(ll j=l/prime[i]+(l%prime[i]>0);j*prime[i]<=r;j++){ int f=0; while(re[j*prime[i]-l]%prime[i]==0){ re[j*prime[i]-l]/=prime[i]; ans[j*prime[i]-l]*=prime[i]; f=1; } if(f)ans[j*prime[i]-l]=ans[j*prime[i]-l]/prime[i]*(prime[i]-1); } } } int main() { euler(1e7); cin>>a>>b; for(int i=0;i<=b-a;i++)re[i]=i+a,ans[i]=1; euler2(a,b); ll x=0; for(int i=0;i<=b-a;i++){ if(re[i]!=1)ans[i]*=re[i]-1; x+=ans[i]; } cout<<x; }
F
题意:给出一个大于6的这个正整数,把他分解为6个素数的和,保证有解。
小的话就爆搜一下,大的话,偶数分出2 2 2 2,奇数分出2 2 2 3,然后由哥德巴赫猜想,剩下的数一定可以表示成两个素数的和,用Miller-Rabin的板子才行。
#include <bits/stdc++.h> #include<ext/pb_ds/assoc_container.hpp> #include<ext/pb_ds/tree_policy.hpp> #include<ext/pb_ds/hash_policy.hpp> #include<ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; #define rep(i,n) for(int i=1;i<=n;i++) #define ll long long #define pb push_back #define mp make_pair #define st first #define nd second const int N =1e7 + 7 ; ll phi[N],prime[N],sum[N]; int isprime[N],cnt; int a[]={2,3,7,61,24251}; ll mult_mod(ll a,ll b,ll c){ a%=c; b%=c; ll ret=0,tmp=a; while(b){ if(b&1){ ret+=tmp; if(ret>c)ret-=c; } tmp<<=1; if(tmp>c)tmp-=c; b>>=1; } return ret; } ll pow_mod(ll a,ll n,ll mod){ ll ret=1; ll tmp=a%mod; while(n){ if(n&1)ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret; } int check(ll a,ll n,ll x,ll t){ ll ret=pow_mod(a,x,n); ll last=ret; rep(i,t){ ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1)return 1; last=ret; } if(ret!=1)return 1; return 0; } int MR(ll n){ if(n<2)return 0; if(n==2)return 1; if((n&1)==0)return 0; ll x=n-1,t=0; while((x&1)==0)x>>=1,t++; for(int i=0;i<5;i++){ if(check(a[i],n,x,t))return 0; } return 1; } void euler(int n){ phi[1]=1; for(int i=2;i<=n;i++){ if(isprime[i]==0){ prime[++cnt]=i; phi[i]=i-1; } for(int j=1;j<=cnt&&prime[j]*i<=n;j++){ isprime[i*prime[j]]=1; if(i%prime[j]==0){ phi[i*prime[j]]=phi[i]*prime[j]; break; } else phi[i*prime[j]]=phi[i]*phi[prime[j]]; } } for(int i=1;i<=n;i++)sum[i]=sum[i-1]+phi[i]; } int aa[]={2,3,5,7,11,13,17,19}; int f=0; int ans[10]; void dfs(int x,int y){ if(f)return; if(x<0)return; if(y==7){ if(x==0){rep(i,6)cout<<ans[i]<<" ";f=1;return;} return ; } for(int i=0;i<8;i++)ans[y]=aa[i],dfs(x-aa[i],y+1); } int check(ll x){ } int main() { ll n; euler(1e3); int t; cin>>t; while(t--){ f=0; cin>>n; if(n<=20)dfs(n,1); else { if(n%2==1){ cout<<2<<" "<<2<<" "<<2<<" "<<3<<" "; n-=9; } else { cout<<2<<" "<<2<<" "<<2<<" "<<2<<" "; n-=8; } for(int i=1;i<=cnt;i++){ if(MR(n-prime[i])>0){ cout<<prime[i]<<" "<<n-prime[i]; break; } } } cout<<endl; } }