• Codeforces Round #636 (Div. 3)


    A. Candies

    题意

    求出任意一个x,满足(x+2x+4x+⋯+2^{k−1}x=n.),k为任意大于1的数。((3≤n≤10^9))

    思路

    将2的指数的前缀和大表存在Map,然后枚举k,只需要枚举1到sqrt(n)即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    map<long long,int> mmp;
    int main(){
        int T;
        long long p=1,sum=0;
        for(int i=1;i<=32;++i){
            sum+=p;
            mmp[sum]=i;
            p*=2;
        }
        mmp[1]=0;
        cin>>T;
        while(T--){
            int n;
            cin>>n;
            for(int i=1;i<=sqrt(n);++i){
                if(n%i==0&&mmp[n/i]){
                    cout<<i<<endl;
                    break;
                }
                else if(n%i==0&&mmp[i]){
                    cout<<n/i<<endl;
                    break;
                }
            }
        }
        return 0;
    }
    

    B. Balanced Array

    题意

    构造一个长度为n的序列满足:前n/2个数字是偶数,后n/2个数字是奇数,且前n/2个数之和等于后n/2个数之和。((2≤n≤2⋅105))

    思路

    假设让前n/2个数等于2到n之间的偶数,后n/2-1个数等于1到n之间的奇数,将前后的差补在最后一个数上,使得最后一个数是奇数,否则输出“NO”.

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int a[200010];
    int main(){
        int T;
        cin>>T;
        int t=2;
        for(int i=1;i<=100000;++i,t+=2){
            a[i]=t;
        }
        t=1;
        for(int i=100001;i<=200000;++i,t+=2){
            a[i]=t;
        }
        while(T--){
            int n;
            cin>>n;
            if((n/2)%2){
                cout<<"NO
    ";
                continue;
            }
            cout<<"YES
    ";
            for(int i=1;i<=n/2;++i){
                cout<<a[i]<<" ";
            }
            for(int i=100001;i<=100000+n/2;++i){
                if(100000+n/2==i){
                    cout<<a[i]+n/2;
                }
                else cout<<a[i]<<" ";
            }
            cout<<endl;
        }
        return 0;
    }
    

    C. Alternating Subsequence

    题意

    给出一个只有正负数的序列,求出最长的摆动子序列(正负交替),在子序列最长的前提下,子序列之和尽可能地大。((1≤n≤2⋅105))

    思路

    模拟:对正负性相同的连续一段选出值最大的一个加入到序列中去。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL f[200010][2],a[200010];
    int main(){
        int T;
        cin>>T;
        while(T--){
            int n;
            cin>>n;
            for(int i=1;i<=n;++i){
                cin>>a[i];
            }
            LL ans=0;
            for(int i=1;i<=n;){
                LL tmp=-1e18;
                int j=i;
                for(;j<=n;++j){
                    if(a[i]*a[j]>=0){
                        tmp=max(a[j],tmp);
                    }
                    else break;
                }
                i=j;
                ans+=tmp;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    

    D. Constant Palindrome Sum

    题意

    将一个序列的某一个数字替换成1到k的任意一个数,使得最终的序列满足对于所有的(i∈(1,n/2))有:(ai+an−i+1=x)((2≤n≤2⋅10^5,1≤k≤2⋅10^5,1≤ai≤k))

    思路

    x可以等于2到2k之间的任意一个数,那么我们枚举每个二元组,求出不改变时它可以取到的和,改变一个可以取到的和,改变两个可以取到的和各有哪些。
    那么对于可以取到的值去差分,最后求出最小的一个值,就是操作次数最少可以得到的x。

    代码

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    int t[200010],n,m;
    int f[1000010];
    signed main(){
        int T;
        cin>>T;
        while(T--){
            cin>>n>>m;
            for(int i=0;i<=2*m;++i){
                f[i]=0;
            }
            for(int i=1;i<=n;++i){
                cin>>t[i];
            }
            for(int i=1;i<=n/2;++i){
                int a=t[i],b=t[n-i+1];
                int l1=b+1,r1=b+m;
                int l2=a+1,r2=a+m;
                f[min(l1,l2)]++;
                f[a+b]--;
                f[a+b+1]++;
                f[max(r1,r2)+1]--;
                f[2]+=2;
                f[min(l1,l2)]-=2;
                f[max(r1,r2)+1]+=2;
                f[2*m+1]-=2;
            }
            int ans=1000000;
            for(int i=2;i<=m*2;++i){
                f[i]+=f[i-1];
                ans=min(ans,f[i]);
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    

    E. Weights Distributing

    题意

    在一个暂未赋权有m条边的无向图的和m个权值,求出存在有一种赋权的最优方案从a到b到c的最小花费。

    思路

    一定只有两种路线即:

    1. a -> v -> b -> v -> c,即从a到v到b再折返回v到c。
    2. a -> b -> c,即从a到b到c没有走重边,那么也可以变形为:a -> b -> b -> b -> c。

    预处理a,b,c到每个点经过的最少边数,再将p排序求出前缀和。由于b到v的过程走了两次,所以a到b的边权尽可能地小,再取a到v和c到v的边权。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N=200010;
    int h[N],idx;
    typedef long long LL;
    LL p[N*2];
    int d1[N],d2[N],d3[N],q[N];
    struct eg{
        int v,nex;
    }e[N*2];
    void add(int u,int v){
        e[idx]={v,h[u]};
        h[u]=idx++;
    }
    void bfs(int d[],int S){
        int hh=0,tt=0;
        q[tt++]=S;
        d[S]=0;
        while(hh!=tt){
            int u=q[hh++];
            if(hh==N) hh=0;
            for(int i=h[u];~i;i=e[i].nex){
                int v=e[i].v;
                if(d[v]>d[u]+1){
                    d[v]=d[u]+1;
                    q[tt++]=v;
                    if(tt==N) tt=0;
                }
            }
        }
    }
    int main(){
        int T;
        cin>>T;
        while(T--){
            memset(h,-1,sizeof h);idx=0;
            memset(d1,0x3f,sizeof d1);
            memset(d2,0x3f,sizeof d2);
            memset(d3,0x3f,sizeof d3);
            int n,m,a,b,c;
            cin>>n>>m>>a>>b>>c;
            for(int i=1;i<=m;++i)   cin>>p[i];
            sort(p+1,p+1+m);
            for(int i=1;i<=m;++i) p[i]+=p[i-1];
            for(int i=1;i<=m;++i){
                int u,v;
                cin>>u>>v;
                add(u,v);
                add(v,u);
            }
            bfs(d1,a);
            bfs(d2,b);
            bfs(d3,c);
            LL ans=1e18;
            for(int i=1;i<=n;++i){
                int t1=d2[i],t2=d1[i]+d3[i];
                if(t1+t2<=m){
                    ans=min(ans,p[t1]*2+p[t1+t2]-p[t1]);
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    JS中!=、==、!==、===的用法和区别
    Jquery判断Checkbox是否选中三种方法
    C# 信号量 学习
    redis学习资料
    Redis常用命令
    MySQL、HBase、ES的对比
    我对依赖注入,控制反转的理解
    net输出错误日志
    XmlExtensions帮助类
    DatetimeHelper类的编写
  • 原文地址:https://www.cnblogs.com/jjl0229/p/12753011.html
Copyright © 2020-2023  润新知