zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 162 题解

    A. Lucky 7

      签到。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    int main(){
        int n=read();
        while(n){
            if(n%10==7){
                puts("Yes");
                return 0;
            }
            n/=10;
        }
        puts("No");
    
        return 0;
    }
    View Code

    B. FizzBuzz Sum

      签到*2。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    
    int main(){
        int n=read();
        LL ans=0;
        for(int i=1;i<=n;++i){
            if(i%3==0||i%5==0){
                continue;
            }
            else{
                ans+=i;
            }
        }
    
        cout<<ans;
    
        return 0;
    }
    View Code

    C. 给一个上界K,求三个数分别在这三个区间[1-K]内取值时,其gcd之和。

      这个题数据能很轻松出到5000,O(n^2logn)做完,给出5000的做法。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    int cnt[5005];
    
    int main(){
        int n=read();
        LL ans=0;
    
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                int t=__gcd(i,j);
                ++cnt[t];
            }
        }
    
        for(int i=1;i<=n;++i){
            for(int j=1;j<=5000;++j){
                if(cnt[j]){
                    ans+=1ll*cnt[j]*__gcd(j,i);
                }
            }
        }
    
        cout<<ans;
    
        return 0;
    }
    View Code

    D. 给一个字符串,统计三元组(i,j,k)(i<j<k)。其下标对应的字母不同,且三元组不成等差数列。

      枚举两个,二分第三个,剔掉成等差数列的情况。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    vector<int> p[3];
    
    char s[4005];
    
    int main(){
        int n=read();
        scanf("%s", s+1);
    
        vector<char> t;
        t.PB('R');
        t.PB('G');
        t.PB('B');
    
        for(int i=1;i<=n;++i){
            if(s[i]=='R')p[0].PB(i);
            if(s[i]=='G')p[1].PB(i);
            if(s[i]=='B')p[2].PB(i);
        }
    
        LL ans=0;
    
        for(int i=1;i<=n;++i){
            for(int j=i+1;j<=n;++j){
                if(s[i]!=s[j]){
                    for(int k=0;k<=2;++k){
                        if(t[k]!=s[i]&&t[k]!=s[j]){
                            int num=p[k].end()-lower_bound(p[k].begin(),p[k].end(),j);
                            ans+=num;
                            int pos=lower_bound(p[k].begin(),p[k].end(),j+j-i)-p[k].begin();
                            if(pos<SZ(p[k])&&p[k][pos]==j+j-i)--ans;
                        }
                    }
                }
            }
        }
    
        cout<<ans;
    
        return 0;
    }
    View Code

    E. 现在给N个数,每个数的取值在1-K之间,求它们的gcd之和。

      套路反演入门题,不会的可以先戳莫比乌斯反演

      具体做法就是先枚举gcd,然后反演成带mu函数的式子(其实就是套公式,原理是mu函数的一个性质)。预处理出mu函数前缀和之后,对于gcd的每一个取值,数论分块,快速幂即可。

      (当然,这都是属于吃撑了的做法,真正快速的做法是欧拉反演,一步到位。但由于本人考试时,忘记欧拉的筛子咋写了,就写了个mu的。

      最外层可以再分个块,这样复杂度就变成了O(N*logn)。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline int read(){
        int res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    int powmod(int x, int y){
        int res=1;
        while(y){
            if(y&1)
                res=1ll*res*x%MOD;
            x=1ll*x*x%MOD;
            y>>=1;
        }
        return res;
    }
    
    int mu[MAXN];
    int Prime[MAXN],isNot[MAXN],tol;
    
    void get_mu(int n){
        mu[1]=1;
        for(int i=2;i<=n;++i){
            if(!isNot[i]){
                Prime[++tol]=i;
                mu[i]=-1;
            }
            for(int j=1;j<=tol;++j){
                if(1ll*i*Prime[j]>n)break;
                isNot[i*Prime[j]]=1;
                mu[i*Prime[j]]=-mu[i];
                if(i%Prime[j]==0){
                    mu[i*Prime[j]]=0;
                    break;
                }
            }
        }
    
        for(int i=1;i<=n;++i){
            mu[i]+=mu[i-1];
        }
    }
    
    int main(){
        int n=read();
        int k=read();
    
        get_mu(100005);
    
        LL ans=0;
        for(int i=1;i<=k;++i){
            LL sum=0;
            for(int l=1,r;l<=k/i;l=r+1){
                r=(k/i)/((k/i)/l);
                sum+=1ll*(mu[r]-mu[l-1])*powmod((k/i)/l,n);
                sum%=MOD;
            }
            ans+=i*sum;
            ans%=MOD;
        }
    
        ans=(ans%MOD+MOD)%MOD;
        cout<<ans;
    
        return 0;
    }
    View Code

    F. 给一个长度为n序列,选择n/2个数,使得其和最大。

      我就要开二维数组你能秒我?开不下就用map开第二维。按照题意模拟即可,一个关键剪枝加上之后就能轻松通过。

      我的分析应应该是,空白的个数不能超过(n+1)/2个,且每一个之间距离相差不能超过1。这直接导致解的空间不会太大,就水过去了,复杂度就很玄学(我不会。

    #include<bits/stdc++.h>
    
    #define all(x) x.begin(),x.end()
    #define fi first
    #define sd second
    #define lson (nd<<1)
    #define rson (nd+nd+1)
    #define PB push_back
    #define mid (l+r>>1)
    #define MP make_pair
    #define SZ(x) (int)x.size()
    
    using namespace std;
    
    typedef long long LL;
    
    typedef vector<int> VI;
    
    typedef pair<int,int> PII;
    
    inline LL read(){
        LL res=0, f=1;char ch=getchar();
        while(ch<'0'|ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=res*10+ch-'0';ch=getchar();}
        return res*f;
    }
    
    const int MAXN = 200'005;
    
    const int MOD = 1000000007;
    
    const LL inf = (LL)1e18;
    
    void addmod(int& a, int b){a+=b;if(a>=MOD)a-=MOD;}
    int mulmod(int a, int b){return 1ll*a*b%MOD;}
    
    template<typename T>
    void chmin(T a, T b){if(a>b)a=b;}
    
    template<typename T>
    void chmax(T a, T b){if(b>a)a=b;}
    
    LL a[MAXN], n;
    map<int,long long> H[MAXN];
    
    LL dfs(int idx, int cnt){
        if(idx>=n+1){
            if(cnt==n/2)return 0;
            else return -inf;
        }
    
        if(H[idx].count(cnt))return H[idx][cnt];
    
        if((cnt+(n-idx+2)/2)<n/2)return -inf;
    
        return H[idx][cnt]=max(dfs(idx+1,cnt),dfs(idx+2,cnt+1)+a[idx]);
    }
    
    int main(){
        n=read();
        for(int i=1;i<=n;++i)a[i]=read();
    
        cout<<dfs(1,0);
    
        return 0;
    }
    View Code

      

  • 相关阅读:
    DataTableToJSON
    css hack
    把网络数据流转换成图片类
    递归(转)
    SQL 锁
    观察者
    yield
    开闭原则(转)
    迪米特法则(最少知道原则)(转)
    sql 游标
  • 原文地址:https://www.cnblogs.com/JohnRan/p/12690421.html
Copyright © 2011-2022 走看看