Codeforces Round #702 题解

A题

找两两比列,按2的次幂进行划分

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=1e5+200;
const int mod=1e9+7;
int a[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        int ans=0;
        for(i=1;i<n;i++){
            int x=max(a[i],a[i+1]);
            int y=min(a[i],a[i+1]);
            int d=x/y;
            if(x%y)
                d++;
            int tmp=0;
            for(int j=1;j<10;j++){
                if(pow(2,j)<d){
                    tmp++;
                }
                else{
                    break;
                }
            }
            ans+=tmp;
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

B题

暴力做,我们发现每个位置的数相同,因此模拟增量,从mod 0开始计算差值,之后进行平移

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=1e5+200;
const int mod=1e9+7;
int a[N];
int cnt[5];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
        }
        for(i=0;i<3;i++)
            cnt[i]=0;
        for(i=1;i<=n;i++){
            if(a[i]%3==0)
                cnt[0]++;
            if(a[i]%3==1)
                cnt[1]++;
            if(a[i]%3==2)
                cnt[2]++;
        }
        int x=n/3;
        int ans=0;
        if(cnt[0]<x){
            cnt[2]-=(x-cnt[0]);
            ans+=(x-cnt[0]);
        }
        else{
            cnt[1]+=(cnt[0]-x);
            ans+=(cnt[0]-x);
        }
        if(cnt[1]<x){
            ans+=(x-cnt[1])*2;
        }
        else{
            ans+=(cnt[1]-x);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

C题

模拟题,因为开三次方的大小不会太大,因此枚举每个平方数计算

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=1e5+200;
const int mod=1e9+7;
ll a[N];
map<ll,int> m1;
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    for(ll i=1;i<=10000;i++){
        a[i]=i*i*i;
        m1[a[i]]++;
    }
    while(t--){
        ll x;
        cin>>x;
        int flag=0;
        for(int i=1;i<=10000;i++){
            if(m1[x-a[i]]){
                flag=1;
                break;
            }
        }
        if(flag){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}
View Code

D题

模拟建树,01位置分别代表左右子树,log跳跃,记录每个位置的pos,从根节点开始,根据相对位置跳转

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=1e5+200;
const int mod=1e9+7;
int a[N];
int g[200][200];
int pos[N],depth[N];
void dfs(int u,int fa){
    depth[u]=depth[fa]+1;
    for(int i=0;i<=1;i++){
        int j=g[u][i];
        if(j==0)
            continue;
        dfs(j,u);
    }
}
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i;
        for(i=1;i<=n;i++){
            cin>>a[i];
            pos[a[i]]=i;
            g[i][0]=g[i][1]=0;
        }
        int rt=n;
        depth[rt]=1;
        for(i=n-1;i>=1;i--){
            int tmp=rt;
            while(1){
                if(pos[i]<pos[tmp]){
                    if(g[tmp][0]){
                        tmp=g[tmp][0];
                    }
                    else{
                        g[tmp][0]=i;
                        break;
                    }
                }
                else{
                    if(g[tmp][1]){
                        tmp=g[tmp][1];
                    }
                    else{
                        g[tmp][1]=i;
                        break;
                    }
                }
            }
        }
        dfs(rt,0);
        for(i=1;i<=n;i++){
            cout<<depth[a[i]]-1<<" ";
        }
        cout<<endl;
    }
    return 0;
}
View Code

E题

对于一个人最优解就是把比他小的全吃完再往后比,因此记录一个前缀和,找到最后一个前缀和不能大于后一个数的位置,后面的大小都可以

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=2e5+200;
const int mod=1e9+7;
int a[N],b[N];
map<int,int> m1;
int sign[N];
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i;
        m1.clear();
        for(i=1;i<=n;i++){
            cin>>a[i];
            sign[i]=0;
            b[i]=a[i];
        }
        sort(a+1,a+1+n);
        ll sum=0;
        for(i=1;i<n;i++){
            sum+=a[i];
            if(sum<a[i+1]){
                sign[i]=1;
            }
        }
        for(i=n;i>=1;i--){
            if(sign[i])
                break;
            m1[a[i]]=1;
        }
        cout<<n-i<<endl;
        for(i=1;i<=n;i++){
            if(m1[b[i]]){
                cout<<i<<" ";
            }
        }
        cout<<endl;
    }
    return 0;
}
View Code

F题

类似差分数组的思想,维护前缀后缀,这样枚举C,前面的变成0,后面的变成C即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=2e5+200;
const int mod=1e9+7;
int a[N];
ll pre[N],suf[N],d[N];
map<ll,int> m1;
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int i;
        m1.clear();
        for(i=1;i<=n;i++){
            cin>>a[i];
            m1[a[i]]++;
            pre[i]=suf[i]=d[i]=0;
        }
        suf[n+1]=0;
        d[n+1]=0;
        int cnt=0;
        for(auto x:m1){
            pre[x.second]+=x.second;
            suf[x.second]+=x.second;
            d[x.second]+=1;
        }
        for(i=1;i<=n;i++){
            pre[i]+=pre[i-1];
        }
        for(i=n;i>=1;i--){
            suf[i]+=suf[i+1];
        }
        for(i=n;i>=1;i--){
            d[i]+=d[i+1];
        }
        ll ans=1e9;
        for(i=1;i<=n;i++){
            //cout<<pre[i-1]<<" "<<suf[i+1]<<" "<<d[i]*i<<endl;
            ans=min(ans,pre[i-1]+suf[i+1]-d[i+1]*i);
        }
        cout<<ans<<endl;
    }
    return 0;
}
View Code

G题

一大圈的贡献是相等的,用map的lower_bound进行二分查找分类讨论即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pll;
const int N=2e5+200;
const int mod=1e9+7;
ll a[N];
map<ll,ll> m1;
int main(){
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        ll n,m;
        cin>>n>>m;
        m1.clear();
        int i;
        ll row=0,mx=0,mxid=0;
        for(i=1;i<=n;i++){
            cin>>a[i];
            row+=a[i];
            if(row>mx){
                mx=row;
                mxid=i;
                m1[mx]=i;
            }
        }
        for(i=1;i<=m;i++){
            ll x;
            cin>>x;
            auto it=m1.lower_bound(x);
            if(it==m1.end()&&row<=0){
                cout<<-1<<" ";
                continue;
            }
            else if(it==m1.end()){
                auto lst=m1.end();
                --lst;
                int nd=(x-lst->first+row-1)/row;
                it=m1.lower_bound(x-nd*row);
                cout<<it->second+nd*n-1<<" ";
            }
            else{
                cout<<it->second-1<<" ";
            }
 
        }
        cout<<endl;
    }
    return 0;
}
View Code

 

posted @ 2021-02-17 23:23  朝暮不思  阅读(157)  评论(2编辑  收藏  举报