zoukankan      html  css  js  c++  java
  • Codeforces Round #497 (Div. 1)

    Codeforces Round #497 (Div. 1)


    A. Reorder the Array

    先满足数值较小的位置,每次找恰好大于这个值的一个值即可。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    typedef long long ll;
    const int N = 100200;
    using namespace std;
    struct node{
        int id,x;
        node(){}node(int a,int b){id=a;x=b;}
        bool operator < (const node a)const {
            return x < a.x;
        }
    };
    int n,a[N],b[N];
    vector<node> v;
    vector<int> v2;
    multiset<node> s;
    //map<int,int> M;
    int main() {
        scanf("%d",&n);
        rep(i,1,n) {
            scanf("%d",&a[i]);
            v.pb(node(i,a[i])); // **先满足最小的
            s.insert(node(i,a[i])); // **查找现存元素中恰好比它大的
            //++M[a[i]];
        }
        int ans=0;
        sort(v.begin(),v.end());
    //    for(auto tx: v) printf("%d %d
    ",tx.id,tx.x);puts("");
    //    for(auto tx: s) printf("%d %d
    ",tx.id,tx.x);puts("");
        for(int i=0;i<v.size();++i) {
            node t = v[i];//printf("%d %d --> ",t.id,t.x);
            set<node>::iterator it = s.upper_bound(t);
            if(it!=s.end()) {
                b[t.id] = (*it).x; //printf("%d %d",(*it).id,(*it).x);
                //--M[(*it).x];
                ++ans;
                s.erase(it);
            }
            //puts("");
        }
        printf("%d
    ",ans);
        return 0;
    }
    
    

    B. Pave the Parallelepiped

    比赛时,只推出了几种特殊情况的规律。下来学习了一下,将 A, B, C 的所有约数分类为只在A中,只在B中,只在 C 中,只在 AB 中,等7种类别。枚举a, b, c分别属于哪个类别,同时保证要包含A,B,C的约数。计算时,有三个不同的类别,两个类别相同一个不同,三种相同的。在一个类别内,要挑出2个约数时,有两种情况相同或不同,要挑出3个约数时,有3种情况,各不相同,有两个相同,三个相同,分别计算。这题确实学到很多,讨论能力太差了,从一开始就找规律思考一点都不深入。

    #include <bits/stdc++.h>
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    #define pb push_back
    typedef long long ll;
    const int N = 100200;
    using namespace std;
    int n,p[N],notp[N],d[N];
    int cal_p(int x) {int ans=1;
        for(int i=2;i*i<=x;++i)if(x%i==0){
            int tmp=0;
            while(x%i==0)x/=i,++tmp;
            ans*=(tmp+1);
        }
        if(x>1)ans*=2;
        return ans;
    }
    vector<int> va,vb,vc;
    int A = 1, B = 2, C = 4, AB = 3, BC = 6, AC = 5, ABC = 7;//000 : BCA
    void init() {
        notp[1]=1;d[1]=1;
        for(int i=2;i<=100000;++i) {
            if(!notp[i])p[++p[0]] = i,d[i] = 2;
            for(int j=1;j<=p[0]&&p[j]*i<=100000;++j) {
                notp[i*p[j]]=1;
                if(i%p[j]==0) {
                    d[i*p[j]] = cal_p(i*p[j]);
                    break;
                }
                d[i*p[j]] = d[i]*d[p[j]];
            }
        }
        va.pb(A),va.pb(AB),va.pb(AC),va.pb(ABC);
        vb.pb(B),vb.pb(AB),vb.pb(BC),vb.pb(ABC);
        vc.pb(C),vc.pb(BC),vc.pb(AC),vc.pb(ABC);
    }
    int a[5];
    ll C3(ll x) {return x + x*(x-1)/2*2 + x*(x-1)*(x-2)/6LL;}
    ll C2(ll x) {return x + x*(x-1)/2LL;}
    int num[N],vis[N];
    int main() {
        init();
        scanf("%d",&n);
        rep(ti,1,n) {int AA,BB,CC;
            scanf("%d%d%d",&AA,&BB,&CC);
            int gab = __gcd(AA,BB), gbc = __gcd(BB,CC), gac = __gcd(AA,CC);
            int gabc = __gcd(gab,CC);
            num[ABC] = d[gabc];
            num[AB] = d[gab] - num[ABC];
            num[AC] = d[gac] - num[ABC];
            num[BC] = d[gbc] - num[ABC];
            num[A] = d[AA] - num[AB] - num[AC] - num[ABC];
            num[B] = d[BB] - num[AB] - num[BC] - num[ABC];
            num[C] = d[CC] - num[AC] - num[BC] - num[ABC];
            ll ans = 0;
    
            for(int i=0;i<va.size();++i)
            for(int j=0;j<vb.size();++j)
            for(int k=0;k<vc.size();++k) {
                a[0] = va[i];a[1] = vb[j];a[2]=vc[k];
                sort(a,a+3);
                if(vis[a[0]*100+a[1]*10+a[2]])continue;
                vis[a[0]*100+a[1]*10+a[2]]=1;
                if(a[0]==a[1]&&a[1]==a[2]) ans+=1LL*C3(num[a[0]]);
                else if(a[0]==a[1]) ans+=1LL*num[a[2]]*C2(num[a[0]]);
                else if(a[1]==a[2]) ans+=1LL*num[a[0]]*C2(num[a[1]]);
                else ans+=1LL*num[a[0]]*num[a[1]]*num[a[2]];
            }
            for(int i=0;i<va.size();++i)
            for(int j=0;j<vb.size();++j)
            for(int k=0;k<vc.size();++k) {
                a[0] = va[i];a[1] = vb[j];a[2]=vc[k];
                sort(a,a+3);
                vis[a[0]*100+a[1]*10+a[2]]=0;
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    洛谷 P1508 Likecloud-吃、吃、吃
    Codevs 1158 尼克的任务
    2017.10.6 国庆清北 D6T2 同余方程组
    2017.10.6 国庆清北 D6T1 排序
    2017.10.3 国庆清北 D3T3 解迷游戏
    2017.10.3 国庆清北 D3T2 公交车
    2017.10.3 国庆清北 D3T1 括号序列
    2017.10.4 国庆清北 D4T1 财富
    2017.10.7 国庆清北 D7T2 第k大区间
    2017.10.7 国庆清北 D7T1 计数
  • 原文地址:https://www.cnblogs.com/RRRR-wys/p/9329627.html
Copyright © 2011-2022 走看看