[Explanations] Codeforces Round # 600 (Div.2)

Codeforces Round #600(Div.2)

https://codeforces.com/contest/1253/problem

A.Single Push

Ideas: the array you subtract, then get ba. If all 0, or only for some non-zero and the same figure is feasible, otherwise infeasible. Specific implementation, it can be found both sides to the intermediate pointer to the first number is not 0, and then determines whether or not the intermediate are the same number. Complexity \ (O (n-) \) .

Note: multiple sets of data have to determine whether the need to empty. Here I a [n + 1] is not cleared, the results WA on test55 ......

AC Code:

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
int a[M];
int main(){
    int T;
    scanf("%d",&T);
    for (int z=1;z<=T;++z){
        int n;
        scanf("%d",&n);
        for (int i=1;i<=n;++i)
            scanf("%d",&a[i]);
        a[n+1]=0;
        int c;
        for (int i=1;i<=n;++i){
            scanf("%d",&c);
            a[i]-=c;
        }
        bool v=true;
        int l=1,r=n;
        while(l<=n&&a[l]==0)
            ++l;
        while(r>l&&a[r]==0)
            --r;
        int std=a[l];
        if (std>0)
            v=false;
        else
            for (int i=l;i<=r;++i)
                if (a[i]!=std){
                    v=false;
                    break;
                }
        if (v)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
} 

B.Silly Mistake

Idea: you can use unordered_set record who is currently in office inside, with unordered_map to record whether a person entered the office. For each event, if positive, it is determined whether or not it has been previously entered, if you have entered it is illegal, otherwise record 1 this man, and added set; if it is negative, then first determine what is in the set, if is not illegal, otherwise delete this person, then judge whether the office here at empty , if empty directly as end of the day (because the topic that day can easily be divided). Complexity \ (O (n-) \) .

note:

  1. \ (O (1) \) Clear STL: a built directly into the same, each direct st = st0;
  2. Many cases can be used to optimize unordered_map unordered_set and complexity (remove the log), but be careful stuck out (hash). But I can not think of a way to ensure that stuck out, probably meaning to write a randomized hash, as detailed neal's blog (on cf).

AC Code:

#include<bits/stdc++.h>
using namespace std;
const int M=2e6+20,P=1e6;
vector<int> vec;
unordered_set<int> st;
unordered_map<int,int> mp,mp0;
int c[M];
int main(){
    int n;
    scanf("%d",&n);
    bool v=true;
    for (int i=1;i<=n;++i)
        scanf("%d",&c[i]);
    for (int i=1;i<=n;++i){
        if (c[i]>0){
            if (mp[c[i]+P]){
                v=false;
                break;
            }
            else
                st.insert(c[i]),mp[c[i]+P]=1;
        }
        else{
            if (st.count(-c[i])){
                st.erase(-c[i]);
                if (st.empty())
                    vec.push_back(i),mp=mp0;
            }
            else{
                v=false;
                break;
            }
        }
    }
    if (!st.empty())
        v=false;
    if (!v)
        printf("-1\n");
    else{
        printf("%d\n%d",vec.size(),vec[0]);
        for(int i=1;i<vec.size();++i)
            printf(" %d",vec[i]-vec[i-1]);
    }
    return 0;
}

C.Sweets Eating

Ideas: First, greed is easy to think just always eat \ (a_i \) more sugar, so the total minimum penalty. But the problem required output k = 1-m in all cases. After a few examples can be found just from small to large, then k is incremented by one for each, the answer will be added after the sort \ (a [k \% m ], a [k \% m + m], a [k \% m + 2M] ...... \) , index not greater than k. So long as the first row of a sequence, then after each pretreatment \ (k \% m \) prefix and then again scan the output answer to. Complexity \ (O (nlogn) \) .

Note: do not open LL see fathers.

AC Code:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int M=2e5+20;
int a[M];
vector<LL> mmd[M]; 
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i)
        scanf("%d",&a[i]); 
    sort(a+1,a+n+1);
    for(int i=0;i<m;++i){
        int j=1;
        mmd[i].push_back(a[i]);
        while(j*m+i<=n)
            mmd[i].push_back(mmd[i][j-1]+a[j*m+i]),++j;
    }
    LL ans=a[1];
    printf("%lld",ans);
    for (int i=2;i<=n;++i){
        ans+=mmd[i%m][i/m];
        printf(" %lld",ans);
    }
    putchar('\n');
    return 0;
}

D.Harmonious Graph

Thinking: This question can be found, the topic description is equivalent to: l and r if there is a path, between l, r all points must be communication. Then we can think of using disjoint-set (dsu) to deal with.

First through each one side are combined, and then after each scan to find out over the set, each record set cnt number of elements, the minimum point and the maximum point serial number mn mx.

If the mx-mn + 1 = cnt, then that element of this collection is Mn \ (\ the SIM \) MX, the meaning of the questions to meet the conditions.

If the mx-mn + 1 <cnt, then explained in other collections, we want to have a set of two linked up some points before they can be put into missing the point. Then connect two sets only need to add an edge, plus a direct answer to.

Of course, a large collection of finished after the connection may still not satisfy mx-mn + 1 = cnt, then continuing the above steps until this condition is satisfied so far. When all the set conditions are met, you can output the answer.

So how to find the missing collection point where it? We disjoint-set to record only cnt, mn, mx each, all disjoint-set in accordance with mn from small to large. If the i-th set of conditions are not satisfied, it will certainly be missing i + 1-th mn point set, it will be i and i + 1 set of the merger, if the merger is not satisfied to continue until satisfied so far. This can be achieved with a priority queue.

Complexity is disjoint-set and priority queues \ (O (nlogn) \) , to achieve constant bit big, but had lost 140ms.

Note: if there \ (O (n + m) \) approach ...... look back Tutorial it.

AC Code:

#include<bits/stdc++.h>
using namespace std;
const int M=2e5+20;
int road[M];
int fnd(int x){
    return (x==road[x])?x:road[x]=fnd(road[x]);
}
void merge(int u,int v){
    road[fnd(u)]=fnd(v);
}
struct Bcj{
    int mn,mx,cnt;
    Bcj(int a=1e9+7,int b=0,int c=0):mn(a),mx(b),cnt(c){}
    void proc(int i){
        mn=min(mn,i);
        mx=max(mx,i);
        ++cnt;
    }
    void clear(){
        mn=1e9+7;
        mx=cnt=0;
    }
    void merg(Bcj x){
        mn=min(mn,x.mn);
        mx=max(mx,x.mx);
        cnt+=x.cnt;
    }
}bcj[M];
struct cmp{
    bool operator()(Bcj x,Bcj y){
        return x.mn>y.mn;
    }
};
priority_queue<Bcj,vector<Bcj>,cmp> q;
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int a,b;
    for (int i=1;i<=n;++i)
        road[i]=i;
    for (int i=1;i<=m;++i){
        scanf("%d%d",&a,&b);
        merge(a,b);
    }
    for(int i=1;i<=n;++i)
        bcj[i].mx=bcj[i].mn=i,bcj[i].cnt=1;
    for(int i=1;i<=n;++i)
        if (i!=fnd(i)&&bcj[i].mx)
            bcj[fnd(i)].proc(i),bcj[i].clear();
    //for(int i=1;i<=n;++i)
    //  cout<<bcj[i].mn<<' '<<bcj[i].mx<<bcj[i].cnt<<endl;
    for(int i=1;i<=n;++i)
        if (bcj[i].mx)
            /*cout<<bcj[i].mn<<' '<<bcj[i].mx<<' '<<bcj[i].cnt<<endl,*/q.push(bcj[i]);
    Bcj prs;
    int ans=0;
    while(!q.empty()){
        Bcj prs=q.top();
        q.pop();
        while(prs.cnt!=prs.mx-prs.mn+1){
            prs.merg(q.top());
            q.pop();
            ++ans;
        }
    }
    printf("%d\n",ans);
    return 0;
}

E.Antenna Coverage

The meaning of problems: a street m points [. 1, m], with n transmitting stations, each transmitting station has two parameters \ (x_i \) and \ (S_I \) , represents a transmitting station located in \ (x_i \) , can cover \ ([x_i-S_I, S_I + S_I] \) . We can spend 1coin each transmitting station \ (s_i \) increased by 1, and asked how many coins to spend at least be able to completely cover [1, m]. Ensure that the two transmitting stations will not be in the same location. \ (. 1 \ n-Leq \ Leq 80 \) , \ (n-\ Leq m \ Leq 100000 \) .

Ideas: VP of time to see the range of data should be guessed dp, but I never thought how transfer. Should actually not hard to figure. Provided dp [i] denotes a cover [1, i] minimum cost, then there are two transfer ways:

  1. Directly from the program transferred from [1, i-1] is. If the i has been covered, then dp [i] = dp [i-1]; if i is not covered at, let i-1 that covers the re-expansion of the base station 1, there dp [i] = dp [i-1] +1.
  2. Right endpoint <= i is transferred from the base station. There dp [i] = min (dp [i], i-ant [j] .r + dp [max (2 * ant [j] .xi-1,0)]). Wherein Ant [j] indicates the j-th base station, r represents a base station \ (x_j S_j + \) . This step is to enumerate all eligible base station, the transfer complexity is \ (O (the n-) \) .

Answer dp [m], is covered by determining whether the array requires pre-established vis pretreatment [1, m] interval, the complexity is the worst \ (O (nm) \) , DP is the complexity of the \ (O (mn ) \) , so the overall complexity is \ (O (nm) \) .

note:

  1. To add a (x = 0, s = 0) of the base station. Because with this base station to cover the range of any program is the worst, it will not affect the answer (always take the minimum).
  2. Note pretreatment and when not to cross-border dp left the minimum is zero.

AC Code:

#include<bits/stdc++.h>
using namespace std;
const int M=1e5+20;
struct Ant{
    int x,s,l,r;
    Ant(int a=0,int b=0,int c=0,int d=0):x(a),s(b),l(c),r(d){}
    bool operator<(Ant x){
        return r<x.r;
    }
}ant[100];
int dp[M],vis[M];
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i){
        int x,s;
        scanf("%d%d",&x,&s);
        ant[i]=Ant(x,s,x-s,x+s);
        for(int j=max(0,x-s);j<=min(m,x+s);++j)
            vis[j]=1;
    }
    dp[0]=0;
    for (int i=1;i<=m;++i){
        if (vis[i])
            dp[i]=dp[i-1];
        else
            dp[i]=dp[i-1]+1;
        for (int j=1;j<=n;++j)
            if (ant[j].r<=i)
                dp[i]=min(dp[i],i-ant[j].r+dp[max(2*ant[j].x-i-1,0)]);
    }
    printf("%d\n",dp[m]);
    return 0;
}

to sum up

This time the title D made out, although ABC code implementation and bigwigs about the same, but it feels written in front of the old problems, write a little slow, but ABC WA out of each, indicating the style and habit of writing code or do not well, D title want faster, praise yourself. E do not really thought out the question should be, but was also unlikely to want to write. Cf fight tomorrow night on 1800.

Guess you like

Origin www.cnblogs.com/diorvh/p/11886557.html