• [EOJ]2019 ECNU XCPC April Selection #1


    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;
    }
    View Code

    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;
    
        }
    }
    View Code

    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;
    }
    View Code

    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;
        }
    
    }
    View Code
  • 相关阅读:
    wince5.0 key
    CSS基础知识思维导图xmind
    切图
    头部标签集
    List和Set的区别
    PicGo + Gitee 实现 Markdown 图床
    GitHub Pages 与 Gitee Pages 上的 Jekyll
    Agile, CI/CD,DevOps
    你还不了解DevOps? 看这篇就够了
    DevOps实践心得
  • 原文地址:https://www.cnblogs.com/xutianshu/p/10650996.html
Copyright © 2020-2023  润新知