zoukankan      html  css  js  c++  java
  • Codeforces Round #709 (Div. 2, based on Technocup 2021 Final Round)

    A. Prison Break

    很明显是n*m

    B. Restore Modulo

    乱搞搞过得去的,讨论了一下增情况和减情况这样。

    wa了两发

    #include<bits/stdc++.h>
    #define inf 1e18
    #define ll long long
    #define MAX 1000001
    const ll N = 1e5+7;
    const ll mod = 1e18;
    using namespace std;
    ll a[N];
    int main(){
        ll t;cin>>t;
        while(t--){
            ll n,m,maxx=-1,ff=0;cin>>n;
            ll d=0,z=0,flag=0;
            for(int i=1;i<=n;++i){
                cin>>a[i];
                maxx=max(a[i],maxx);
            }
            for(int i=2;i<=n;++i){
                ll x=a[i]-a[i-1];
                if(x>0){
                    if(d==0)d=x;
                    else if(x!=d)    ff=1;
                }
                else if(x<0){
                    if(z==0)z=x;
                    else if(x!=z)    ff=1;
                }
                else{
                    flag=1;
                }
            }
            if(ff==1){
                printf("-1
    ");
                continue;
            }
            if(flag==1&&(d>0||z<0)){
                printf("-1
    ");
                continue;
            }
            if(d>0&&z<0){
                m=d-z;
                if(m<maxx){
                    printf("-1
    ");
                }
                else{
                    printf("%lld %lld
    ",m,d);
                }
            }
            else{
                printf("0
    ");
            }
        }
        return 0; 
    }

    C. Basic Diplomacy

    题意:给定n个人和m天

    每天会给一些人可以选

    要求最多被选的人的次数不超过 向上取整m/2

    有一些天只能选一个。

    如果这些被迫选的人的其中某个已经过要求了,那直接出NO

    如果这些被迫选的人已经占据了是k天。0≤k≤ (向上取整m/2)

    剩下的m-k天还没选,每天都至少有两个人可以选。

    极端化情况,k天都是A占据的,剩下两天都只有A和B。测试最困难的情况。

    此时

    A 占据 k天 0 ≤ k ≤ (m+1)/2  A/B 共同占据(m-k)天

    先设A= (m+1)/2天,不关k的情况,k小就往共同里面填,A不够了填B= m-(m+1)/2  <  (m+1)/2

    这样构造满足k的任意情况,证明结束。

    如果可以的话,也可以试试网络流

    #include<bits/stdc++.h>
    #define inf 1e18
    #define ll long long
    #define MAX 1000001
    const ll N = 1e5+7;
    const ll mod = 1e18;
    using namespace std;
    int vis[N],vis2[N],n,m,maxx,ans[N];
    vector<int>G[N];
    int main(){
        ll t;cin>>t;
        while(t--){
            int flag=0;cin>>n>>m;
            for(int i=1;i<=n;++i)vis[i]=vis2[i]=0;
            for(int i=1;i<=m;++i)G[i].clear(),ans[i]=0;
            
            maxx=(m+1)/2;
            for(int i=1;i<=m;++i){
                int x;scanf("%d",&x);
                for(int j=1;j<=x;++j){
                    int q;scanf("%d",&q);
                    G[i].push_back(q);
                }
                if(x==1){
                    vis[G[i][0]]++;
                    if(vis[G[i][0]]>maxx)    flag=1;
                    ans[i]=G[i][0];
                    vis2[G[i][0]]++;
                }
            }
            
            if(flag==1)printf("NO
    ");
            else{
                for(int i=1;i<=m;++i){
                    if(ans[i])    continue;            //避免vis2的重复计算 
                    for(int j=0;j<G[i].size();++j){
                        if(vis2[G[i][j]]<maxx){
                            ans[i]=G[i][j];
                            vis2[G[i][j]]++;
                            break;
                        }
                    }
                }
                
                printf("YES
    ");
                for(int i=1;i<=m;++i)
                    printf("%d ",ans[i]);
                printf("
    ");
            }
        }
        return 0; 
    }
    //之前那样写会出现 前面有别的选择但是已经取了但是后面只能取然后超过的情况。 

    D. Playlist

    参考了某位大佬的代码

    并查集维护循环删除过程中,每个人的下一个。

    但是因为路径压缩优化的原因,我们只能存下一个的左边那一个。

    然后队列维护删除的情况。

    因为新的情况只会在改变之后出现在原来的位置上。

    ----

    线段树+循环列表也能维护这个东西

    #include<bits/stdc++.h>
    #define inf 1e18
    #define ll long long
    #define MAX 1000001
    const ll N = 1e5+7;
    const ll mod = 1e18;
    using namespace std;
    int del[N],a[N],n,fa[N];
    vector<int> ans;
    int nxt(int x){
        return x%n+1;
    }
    int find(int x){
        return fa[x]==x?x:fa[x]=find(fa[x]);
    }
    int main(){
        int t;cin>>t;
        while(t--){
            ans.clear();
            scanf("%d",&n);
            for(int i=1;i<=n;++i){
                scanf("%d",&a[i]);
                fa[i]=i;del[i]=0; 
            }
            queue<int>qe;
            for(int i=1;i<=n;++i)
                if(__gcd(a[i],a[nxt(i)])==1)qe.push(i);
            while(!qe.empty()){
                int x=qe.front();
                qe.pop();
                if(del[x])    continue;
                int y=nxt(find(x));
                fa[x]=find(y);del[y]=1;
                ans.push_back(y);
                if(__gcd(a[x],a[nxt(fa[x])])==1)    qe.push(x);
            }
            printf("%d ",ans.size());
            for(int i=0;i<ans.size();++i)
                printf("%d ",ans[i]);
            puts("");
        }
        return 0;
    } 

     E. Skyline Photo

    推荐阅读

    https://blog.csdn.net/Brian_Pan_/article/details/115065320

    #include<bits/stdc++.h>
    #define inf 1e18
    #define ll long long
    #define MAX 1000001
    const ll N = 3e5+7;
    const ll mod = 1e18;
    using namespace std;
    ll f[N],a[N],b[N],c[N],n;
    struct node{
        ll l,r;
        ll maxn,addv;
    }tr[N<<2];
    void build(ll o,ll l,ll r){
        tr[o].l=l;tr[o].r=r;
        if(l==r){
            return ;
        }
        ll mid=l+r>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
    }
    void pushup(ll o){
        tr[o].maxn=max(tr[o<<1].maxn,tr[o<<1|1].maxn);
    }
    void pushdown(ll o){
        if(tr[o].addv==0)    return ;
        tr[o<<1].addv+=tr[o].addv;
        tr[o<<1].maxn+=tr[o].addv;
        tr[o<<1|1].addv+=tr[o].addv;
        tr[o<<1|1].maxn+=tr[o].addv;
        tr[o].addv=0;
    }
    void update_seg(ll o,ll a,ll b,ll k){
        if(a<=tr[o].l&&tr[o].r<=b){
            tr[o].addv=tr[o].addv+k;
            tr[o].maxn=tr[o].maxn+k;
            return ;
        }
        pushdown(o);
        ll mid=tr[o].r+tr[o].l>>1;
        if(a<=mid)    update_seg(o<<1,a,b,k);
        if(b>mid)    update_seg(o<<1|1,a,b,k);
        pushup(o);
    }
    void update_pos(ll o,ll pos, ll v){
        if(tr[o].l==tr[o].r){
            tr[o].maxn=v;
            return ;
        }
        ll mid=tr[o].r+tr[o].l>>1;
        if(pos<=mid)    update_pos(o<<1,pos,v);
        else        update_pos(o<<1|1,pos,v);
        pushup(o);
    }
    ll query(ll o,ll a,ll b){
        if(a<=tr[o].l&&tr[o].r<=b)
            return tr[o].maxn;
        pushdown(o);
        ll ans=-inf;
        ll mid=tr[o].l+tr[o].r>>1;
        if(a<=mid)    ans=query(o<<1,a,b);
        if(b>mid)    ans=max(ans,query(o<<1|1,a,b));
        return ans;
    }
    int main(){
        scanf("%lld",&n);
        build(1,0,n);
        for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
        for(int i=1;i<=n;++i)scanf("%lld",&b[i]);
        a[0]=-1;f[1]=0;
        int cnt=1;
        for(int i=1;i<=n;++i){
            while(a[c[cnt]]>=a[i] && cnt){
                update_seg(1,c[cnt-1],c[cnt]-1,-b[c[cnt]]);
                //c[cnt-1]到c[cnt]-1减去b[c[cnt]]
                --cnt;
            }
            update_seg(1,c[cnt],i-1,b[i]);
            //c[cnt]到i-1加上b[i]
            f[i]=query(1,0,i-1);
            update_pos(1,i,f[i]);
            //单点修改 maxx i为fi 
            c[++cnt]=i;
        }
        printf("%lld
    ",f[n]);
        return 0;
    }
    View Code
  • 相关阅读:
    qml: QtCharts模块得使用(数据整合和显示) ---- <二>
    qml: QtCharts模块的使用(基本配置)------<一>
    【转载】Qt之JSON生成与解析
    qml: 支持的基本类型
    opencv: 基本知识;
    qml: 模块定义与使用
    Android studio开发中遇到的错误
    阅读笔记——《人月神话》5
    Android studio Adapter基础
    Android studio Date & Time组件2
  • 原文地址:https://www.cnblogs.com/PdrEam/p/14572508.html
Copyright © 2011-2022 走看看