• Codeforces Round #452 (Div. 2)


    A:水题

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    int main()
    {
        int n;
        scanf("%d",&n);
        int one=0,two=0;
        for(int i=0;i<n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x==1)one++;
            else two++;
        }
        int ans=0;
        ans+=min(two,one);
        one-=min(two,one);
        printf("%d
    ",ans+one/3);
        return 0;
    }
    /********************
    
    ********************/
    A

    B:也很水,不过我看很多人被kack了,可能处理有点麻烦,我是直接转化成字符串然后匹配

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    string s="312831303130313130313031312831303130313130313031312831303130313130313031312931303130313130313031312831303130313130313031312831303130313130313031312831303130313130313031";
    int main()
    {
        fio;
        int n;
        cin>>n;
        string p="";
        for(int i=0;i<n;i++)
        {
            string te;
            cin>>te;
            p+=te;
        }
        for(int i=0;i<s.size();i++)
        {
            if(s.substr(i,p.size())==p)
            {
                cout<<"YES
    ";
                return 0;
            }
        }
        cout<<"NO
    ";
        return 0;
    }
    /********************
    
    ********************/
    B

    C:有一个n,1到n,分两组,要求和的差最小,直接从大到小贪心

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    int main()
    {
        int n;
        scanf("%d",&n);
        ll sum=(ll)(1+n)*n/2;
        if(sum%2==0)puts("0");
        else puts("1");
        sum/=2;
        vector<int>v;
        for(int i=n;i>=1;i--)
        {
            if(sum-i>=0)
            {
                sum-=i;
                v.pb(i);
            }
        }
        printf("%d ",v.size());
        for(int i=0;i<v.size();i++)
            printf("%d ",v[i]);
        puts("");
        return 0;
    }
    /********************
    
    ********************/
    C

    D:题意:给一个n,求从1到n中选两个数,加起来末尾的9最多的情况数

    题解:先找在5,50,500.。。。那个区间里,然后枚举,末尾9的个数相同的数,然后直接套公式即可

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=40000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    ll p[20];
    int main()
    {
        ll n;
        scanf("%lld",&n);
        if(n<5)
        {
            printf("%lld
    ",(n*n-n)/2);
            return 0;
        }
        p[0]=5;
        for(ll i=1;i<=10;i++)p[i]=p[i-1]*10;
        int id=upper_bound(p,p+10,n)-p;
        --id;
        ll ans=0;
        for(ll i=p[id]*2-1;i<p[id+1]*2-1;i+=p[id]*2)
        {
            if(2*n<=i)break;
          //  cout<<i<<endl;
            ans+=min(i-1,n)-(i+1)/2+1;
            //cout<<ans<<endl;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    /********************
    
    ********************/
    D

    E:题意:n个数,每次删除最左边的连续相同数字最多的那个区间,问要删几次;

    题解:优先队列维护,先按连续数字相同排序,其次按坐标排序,然后对于每次操作,看删除这个区间之后前后会不会连起来,会的话就把这个合并区间加入队列原来的两个删掉,否则不管

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    struct seg{
        int l,r,v,num;
        bool operator <(const seg &rhm)const{
            if(num==rhm.num)return l>rhm.l;
            return num<rhm.num;
        }
    }s[N*10];
    priority_queue<seg>q;
    map<int,int>ma[N];
    int lrtoid[N];
    int pre[N],last[N];
    int Hash[N];
    int main()
    {
        int n,sz=0,id=0,cnt=0;
        scanf("%d",&n);
        scanf("%d",&s[++id].v);
        Hash[cnt++]=s[id].v;
        pre[s[id].l]=-1;
        s[id].l=s[id].r=s[id].num=1;
        for(int i=2;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            if(x==s[id].v)
            {
                s[id].r++,s[id].num++;
            }
            else
            {
                lrtoid[s[id].l]=lrtoid[s[id].r]=id;
                pre[s[id].r+1]=s[id].r;
                last[s[id].r]=s[id].r+1;
                Hash[cnt++]=s[id].v;
                q.push(s[id]);
                ++id;
                s[id].v=x,s[id].l=s[id].r=i,s[id].num=1;
            }
        }
        lrtoid[s[id].l]=lrtoid[s[id].r]=id;
        last[s[id].r]=-1;
        Hash[cnt++]=s[id].v;
        q.push(s[id]);
        sort(Hash,Hash+cnt);
        cnt=unique(Hash,Hash+cnt)-Hash;
        for(int i=1;i<=id;i++)s[i].v=lower_bound(Hash,Hash+cnt,s[i].v)-Hash;
    //    while(!q.empty())
    //    {
    //        seg s=q.top();
    //        q.pop();
    //        printf("%d %d %d %d
    ",s.l,s.r,s.v,s.num);
    //    }
        int ans=0;
        while(!q.empty())
        {
            seg ss=q.top();
            q.pop();
          //  printf("%d %d %d %d
    ",ss.l,ss.r,ss.v,ss.num);
            if(ma[ss.l][ss.r])continue;
            ans++;
            if(pre[ss.l]==-1&&last[ss.r]==-1)break;
            else if(pre[ss.l]==-1&&last[ss.r]!=-1)pre[last[ss.r]]=-1;
            else if(pre[ss.l]!=-1&&last[ss.r]==-1)last[pre[ss.l]]=-1;
            else
            {
                int id1=lrtoid[pre[ss.l]],id2=lrtoid[last[ss.r]];
                if(s[id1].v==s[id2].v)
                {
                    ma[s[id1].l][s[id1].r]=ma[s[id2].l][s[id2].r]=1;
                    s[++id].l=s[id1].l,s[id].r=s[id2].r,s[id].num=s[id1].num+s[id2].num,s[id].v=s[id1].v;
                    lrtoid[s[id].l]=lrtoid[s[id].r]=id;
                    q.push(s[id]);
                }
                else
                {
                    last[s[id1].r]=s[id2].l;
                    pre[s[id2].l]=s[id1].r;
                }
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    /********************
    
    ********************/
    E

    F:题意:一个字符串,m次操作,每次操作删除区间l到r之间的所有字符c,求完成操作后的字符串

    题解:对于每一种字符维护一个set,插入坐标,每次删除就删掉该区间对应坐标,剩下的问题就是如何将给定的区间映射到原区间,我们采用树状数组维护,每次删除该点时,就在树状数组里-1,映射时用二分,复杂度O(nloglogn)

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=200000+10,maxn=200000+10,inf=0x3f3f3f3f;
    
    int sum[N],n,m;
    void add(int x,int v)
    {
        while(x<N)
        {
            sum[x]+=v;
            x+=x&(-x);
        }
    }
    int query(int x)
    {
        int ans=0;
        while(x>0)
        {
            ans+=sum[x];
            x-=x&(-x);
        }
        return ans;
    }
    int change(int x)
    {
        int l=0,r=n+1;
        while(l<r-1)
        {
            int m=(l+r)>>1;
            if(query(m)>=x)r=m;
            else l=m;
        }
        return r;
    }
    set<int>s[123];
    bool vis[N];
    int main()
    {
        fio;
        string p;
        cin>>n>>m>>p;
        for(int i=0;i<n;i++)
        {
            add(i+1,1);
            s[p[i]].insert(i+1);
        }
        while(m--)
        {
            int l,r;
            string te;
            cin>>l>>r>>te;
            l=change(l),r=change(r);
            //cout<<l<<" "<<r<<endl;
            int id=te[0];
            auto x=s[id].lower_bound(l);
            for(;x!=s[id].end();)
            {
                if((*x)>r)break;
                //cout<<(*x)<<"+++++";
                add((*x),-1);
                s[id].erase(x++);
            }
    //        cout<<endl;
    //        for(int i=1;i<=n;i++)cout<<query(i)<<" ";
    //        cout<<endl;
        }
        for(int i=0;i<123;i++)
            for(auto x:s[i])
                vis[x-1]=1;
        for(int i=0;i<n;i++)
            if(vis[i])
                cout<<p[i];
        cout<<"
    ";
        return 0;
    }
    /********************
    10 4
    agtFrgF4aF
    2 5 g
    4 9 F
    1 5 4
    1 7 a
    ********************/
    F
  • 相关阅读:
    Testdisk 操作指南(硬盘分区表恢复)
    ThinkPHP下使用Uploadify插件提示HTTP Error (302)错误的解决办法
    C#获取计算机CPU的温度
    C# 获取显示器的物理尺寸或分辨率
    获取windows 操作系统下的硬件或操作系统信息等
    AD CS relay attack
    内网密码收集[Foxmail]解密
    如果你是业务线的程序员
    浅析php curl_multi_*系列函数进行批量http请求
    memcached讲解
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8082953.html
Copyright © 2020-2023  润新知