ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #813 (Div. 2) (C~D)

2022-08-15 00:31:37  阅读:159  来源: 互联网

标签:return int res Codeforces ans 1e9 Div 813 mx


C. Sort Zero

最开始写了个n2的 TLE了以后 不知道咋优化
只好观察性质 发现我们要维护一个后缀 很多人说要维护前缀 其实也就少跑了60ms 我们维护一个mp[]记录的是哪个数不合法了 然后后面维护后缀时细节有点多 就没啥了

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int M = 1<<10;
const int mod = 1e9+7;
#define int 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);
        map<int,int>mp;
        int mx=0;
        set<int>s;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            s.insert(a[i]);
            if(a[i-1]!=a[i])mp[a[i]]++;
            if(mp[a[i]]>=2){
                mx=max(mx,i);
            }
        }
        int cnt=1;
        for(int i=n;i>=mx+1;i--){
            if(i-1>0){
                if(a[i]>a[i-1]&&mp[a[i-1]]<=1)cnt++;
                else if(a[i]==a[i-1]&&mp[a[i-1]]<=1)continue;
                else break;
            }
        }
        if(mp[a[n]]>=2)cnt=0;
        cout<<s.size()-cnt<<endl;
    }
    return ~~(0^_^0);
}

1712D - Empty Graph

看到最大最小值 我们考虑二分 要是我们check(mid)时 有a[i]<ans/2上取整 那比不可能使其存在 我们让他修改到1e9或者随便一个大于等于ans/2的值都可以
最后我们考虑k剩下多少 要是k剩下2那么一定可以让一对变成1e9其他都是合法的 自然return 1 k要是不剩 我们就要查看每对有没有大于ans的 有就return1
最后k要是剩下1 我们分情况讨论 要是k原本就是2以上的 那我们已经变了一个1e9了 那自然在其旁边变个1e9 就可以了 要是原本只有1 那我们必须check每个的最大值 让后看其最大值>=ans

#include <bits/stdc++.h>
using namespace std;
const int N = 1e4+10;
const int M = 1<<10;
const int mod = 1e9+7;
#define int 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 n,k;
vector<int>a;
bool check(int ans){
    int res=0,mx=0;
    auto b=a;
    for(int i=0;i<n;i++){
        if((ans+1)/2>b[i]){
            b[i]=1e9;
            res++;
        }
    }
    int maxv=0;
    for(int i=0;i<n;i++){
        maxv=max(maxv,b[i]);
        if(i<n-1)mx=max(mx,min(b[i],b[i+1]));
    }
    if(k>=res){
        if(k==res){
            return mx>=ans;
        }else if(k==res+1){
            if(k==1){
                return maxv>=ans;
            }else{
                return true;
            }
        }else return true;
    }else return false;
}
signed main(){
    fast
    int T;cin>>T;
    while(T--){
        cin>>n>>k;
        a.clear();
        for(int i=1;i<=n;i++){int x;cin>>x;a.push_back(x);}
        int l=0,r=1e9;
        while(l<r){
            int mid=(l+r+1)/2;
            if(check(mid))l=mid;
            else r=mid-1;
        }
        cout<<l<<endl;
    }
    return ~~(0^_^0);
}

还有就是关于这道贪心的证明 我看很多人都没解释 我这里通俗解释一下啊 代码就不贴了
我们最大值来源有两个 一个是mn*2 来的 一个就是自身本来权重就大来的
我们贪心处理前k-1个 再枚举最后一个1e9放哪 可以抽象看成我们把一个1e9放在另一个1e9(其实是大于ans的就可以)旁边 然后我们就可以get一个mn*2
但是枚举这个确实包括了自身本来权重就大这个是为什么呢 换言之 为啥自身本来权重就大 要从小到大删 其实我写这段话的时候就清楚了 我们乱搞出来就是要删第k短的边
所以很多人写的题解是两部分 一步就是删第k短 另一个就是枚举另一个数该放在哪个大数旁边 让后get一个低保

标签:return,int,res,Codeforces,ans,1e9,Div,813,mx
来源: https://www.cnblogs.com/ycllz/p/16586811.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有