Codeforces Round #807 (Div. 2) && Codeforces Round #809 (Div. 2) A~D

今天开始就搬迁到博客园辣!

先809

A

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n,m;cin>>n>>m;
        vector<int>a(n+1);
        set<int>s;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i] < (m-a[i]+1)) {
                if (s.count(a[i])==0)s.insert(a[i]);
                else s.insert(m - a[i] + 1);
            }else{
                if (s.count(m - a[i] + 1)==0)s.insert(m - a[i] + 1);
                else s.insert(a[i]);
            }
        }
        for(int i=1;i<=m;i++){
            if(s.count(i))cout<<'A';
            else cout<<'B';
        }
        cout<<endl;
    }
    return ~~(0^_^0);
}

B

不难发现我们可以绕偶数个回来 并且要是连续的数字也可以直接放上去 麻烦的是奇偶都要走一遍

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
       int n;cin>>n;
       vector<int>v[n+1];
       for(int i=1;i<=n;i++){
           int x;cin>>x;
           v[x].push_back(i);
       }
       for(int i=1;i<=n;i++){
           if(v[i].size()==0){
               cout<<0<<' ';
               continue;
           }
           int cnt=1,flag=0;
           for(int j=0;j+1<v[i].size();j++){
               if(v[i][j+1]==v[i][j]+1||(v[i][j+1]-v[i][j]-1)%2==0)cnt++;
               else if(v[i][j+1]!=v[i][j]+1&&(v[i][j+1]-v[i][j]-1)%2!=0)flag=j;
           }
           int cnt1=1;
           if(flag){
               for(int j=flag;j+1<v[i].size();j++){
                   if(v[i][j+1]==v[i][j]+1||(v[i][j+1]-v[i][j]-1)%2==0)cnt1++;
               }
           }
           cout<<max(cnt1,cnt)<<' ';
       }
       cout<<endl;
    }
    return ~~(0^_^0);
}

C

最开始想到dp 但是好像不是max不可做 然后就简单的想了一下最多只能往后挪一次 那维护一个前缀和就可以了

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
int q;
signed main(){
    fast
    int T;cin>>T;
    while(T--){
       int n;cin>>n;
       vector<int>a(n+1);
       int sum=0;
       for(int i=1;i<=n;i++){
           cin>>a[i];
       }
       vector<int>w(n+1);
       for(int i=2;i<=n-1;i++){
           w[i]=max(max(a[i-1],a[i+1])+1-a[i],q);
           if(i%2==0)sum+=w[i];
       }
        if(n%2){
            cout<<sum<<endl;
            continue;
        }
        vector<int>f(n+1);
        for(int i=n-1;i>=3;i-=2){
            if(i!=n-1)f[i]+=f[i+2]+w[i];
            else f[i]=w[i];
        }
        int cnt=0,res=inf;
        for(int i=2;i<=n-2;i+=2){
            res=min(res,cnt+f[i+1]);
            cnt+=w[i];
        }
        cout<<min(min(cnt,f[3]),res)<<endl;
    }
    return ~~(0^_^0);
}

D1

此题我们可以暴力枚举每一个最小值 然后二分判断其每组里面离他最近的最大值 一定包含最优解
而最小值的范围是啥呢 就是[a1/k,a1] a1/k 肯定是下界 而我们的上界只能是a1 要是a2 的话a1就没有大于a2的值了

时间复杂度是O(n2)

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n,k;cin>>n>>k;
        vector<int>a(n+1);
        vector<int>v[n+1];
        set<int>s;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            for(int j=k;j>=1;j--){
                if(v[i].empty()||v[i].back()!=a[i]/j){
                    v[i].push_back(a[i]/j);
                    s.insert(a[i]/j);
                }
            }
        }
        int l=a[1]/k,r=a[1],ans=inf;
        for(int i=l;i<=r;i++){
            int mx=0;
            if(s.count(i)==0)continue;
            for(int j=1;j<=n;j++){
                int t=lower_bound(v[j].begin(),v[j].end(),i)-v[j].begin();
                mx=max(mx,v[j][t]-i);
            }
            ans=min(ans,mx);
        }
        cout<<ans<<endl;
    }
    return ~~(0^_^0);
}

807

A

我们构造一个最优序列即可

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n,x;cin>>n>>x;
        vector<int>a(n*2);
        for(int i=0;i<n*2;i++){
            cin>>a[i];
        }
        sort(a.begin(),a.end());
        for(int i=0,j=n;j<a.size();i++,j++){
            if(a[j]-a[i]>=x)continue;
            else {
                no;
                goto out;
            }
        }
        yes;
        out:1;
    }
    return ~~(0^_^0);
}

B

不难看出规律就是sum+cnt0

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n;cin>>n;
        vector<int>a(n+1);
        int flag=0,cnt0=0,sum=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(i<n)sum+=a[i];
            if(a[i]&&i<n)flag=1;
            if(flag&&a[i]==0&&i<n)cnt0++;
        }
        if(sum<cnt0){
            cout<<sum+cnt0<<endl;
        }else{
            cout<<sum+cnt0<<endl;
        }
    }
    return ~~(0^_^0);
}

C

没开ll 爆了两次TLE
我们考虑c<=40 那么我们维护每个区间 以及前缀和 每次查询通过区间和前缀查询
考虑到k=1e18 我们二分查找 时间复杂度O(qclogk)

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n,c,q;cin>>n>>c>>q;
        vector<char>a(n+1);
        for(int i=1;i<=n;i++)cin>>a[i];
        pair<int,int>p[c+1];
        vector<int>s(c+1);
        s[0]=n;
        p[0].first=1,p[0].second=n;
        for(int i=1;i<=c;i++){
            int l,r;cin>>l>>r;
            s[i]=s[i-1]+r-l+1;
            p[i].first=l,p[i].second=r;
        }
        while(q--){
            int x;cin>>x;
            while(x>n){
                int t = lower_bound(s.begin(), s.end(), x) - s.begin();
                x -= s[t] - p[t].second;
            }
            cout<<a[x]<<endl;
        }
    }
    return ~~(0^_^0);
}

D

这道题很一眼吧 我们特判左右两边是否相等 然后色块数量是否相等 求距离也是贪心的来求就好了

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 1<<16;
const int mod = 1e9+7;
#define int long long
#define LL long long
#define endl '\n'
#define Endl '\n'
#define yes cout<<"YES"<<endl;
#define no cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);

signed main(){
    fast
    int T;cin>>T;
    while(T--){
        int n;cin>>n;
        string a,b;cin>>a>>b;
        a='?'+a+'0',b='?'+b+'0';
        int l1,r1,l2,r2,cnta=0,cntb=0;
        l1=r1=l2=r2=0;
        vector<pair<int,int>>va;
        vector<pair<int,int>>vb;
        int l,r,flag=0;
        for(int i=1;i<=n;i++){
            if(a[i]=='1'&&flag==0)l=i,flag=1;
            if(a[i]=='1'&&a[i+1]=='0'){
                cnta++;
                r=i;
                flag=0;
                va.emplace_back(l,r);
            }
        }
        for(int i=1;i<=n;i++){
            if(b[i]=='1'&&!flag)l=i,flag=1;
            if(b[i]=='1'&&b[i+1]=='0'){
                cntb++;
                r=i;
                flag=0;
                vb.emplace_back(l,r);
            }
        }
        if(a[1]=='1')l1++;
        if(a[n]=='1')r1++;
        if(b[1]=='1')l2++;
        if(b[n]=='1')r2++;
        if((l1!=l2)||(r1!=r2)){
            cout<<-1<<endl;
        }else{
            if(cnta==cntb){
                int ans=0;
                for(int i=0;i<va.size();i++){
                    ans+=abs(va[i].first-vb[i].first)+abs(va[i].second-vb[i].second);
                }
                cout<<ans<<endl;
            }else cout<<-1<<endl;
        }
    }
    return ~~(0^_^0);
}
posted @ 2022-08-09 18:56  ycllz  阅读(25)  评论(0)    收藏  举报