Educational Codeforces Round 28

Educational Codeforces Round 28 

A. Curriculum Vitae

找分界点,前面全取\(0\)后面全取\(1\)即可

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;

void solve(){
    int n; sci(n);
    vi A(n); for(int &x : A) sci(x);
    int ret = 0;
    for(int i = 0; i <= n; i++){
        int tmp = 0;
        for(int j = 0; j < i; j++) if(A[j]==0) tmp++;
        for(int j = i; j < n; j++) if(A[j]==1) tmp++;
        cmax(ret,tmp);
    }
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

B. Math Show

一种做法是背包,\(dp[i][j]\)表示前\(i\)个任务,得分为\(j\)的最小花费时间

其实枚举一下全做的任务,剩下的丢到优先队列里去或者排个序都可以,没看到可以乱序的条件呜呜

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
const LL inf = 1e12;
LL f[2][60*60];
void solve(){
    int n, k, m;
    sci(n); sci(k); sci(m);
    vi A(k); for(int &x : A) sci(x);
    sort(all(A));
    memset(f,0x3f,sizeof(f));
    int tag = 0;
    f[0][0] = 0;
    for(int i = 1; i <= n; i++){
        tag ^= 1;
        memcpy(f[tag],f[tag^1],sizeof(f[tag]));
        for(int j = 1, s = A[0]; j <= k; s += A[j], j++){
            for(int x = 0; x <= 50 * 50; x++){
                if(f[tag^1][x]>inf) continue;
                cmin(f[tag][x+j+(j==k?1:0)],f[tag^1][x]+s);
            }
        }
    }
    int ret = 0;
    for(int i = 1; i <= 50 * 50; i++) if(f[tag][i]<=m) ret = i;
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

C. Four Segments

其实就是找序列和减去\([a,b)+[c,n)\)的区间和,所以找这两段区间和的最小值即可

可以枚举\(c\)的位置,然后就是在一个前缀中找一个区间最小值,做前缀和然后维护一个前缀最大值的位置即可,因为区间和可以拿两个前缀减一下

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;

void solve(){
    int n; sci(n);
    vl A(n); for(LL &x : A) scl(x);
    int a, b, c;
    LL sub = LLONG_MAX;
    for(LL i = n, suf = 0; i >= 0; i--, suf += A[i]){
        if(suf<sub) sub = suf, a = 0, b = 0, c = i;
        int posa = 0; LL maxx = 0;
        LL pre = 0;
        for(int posb = 0; posb < i; posb++){
            pre += A[posb];
            if(pre>maxx){
                posa = posb + 1;
                maxx = pre;
            }
            if(suf + pre - maxx < sub){
                sub = suf + pre - maxx;
                a = posa, b = posb + 1, c = i;
            }
        }
    }
    cout << a << ' ' << b << ' ' << c << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

D. Monitor

简单题

二分一下,二维前缀和\(check\)一下就好了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
int n, m, k, q;
int pre[507][507];

bool check(int mid, vector<pair<int,pii> > &vec){
    memset(pre,0,sizeof(pre));
    for(int i = 0; i < (int)vec.size(); i++){
        if(vec[i].first>mid) break;
        pre[vec[i].second.first][vec[i].second.second] = 1;
    }
    for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) pre[i][j] += pre[i][j-1] + pre[i-1][j] - pre[i-1][j-1];
    for(int i = k; i <= n; i++) for(int j = k; j <= m; j++) if(pre[i][j] - pre[i][j-k] - pre[i-k][j] + pre[i-k][j-k]==k*k) return true;
    return false;
}

void solve(){
    sci(n); sci(m); sci(k); sci(q);
    if(!q){
        cout << -1 << endl;
        return;
    }
    vector<pair<int,pii> > vec(q);
    for(auto &p : vec) sci(p.second.first), sci(p.second.second), sci(p.first);
    sort(all(vec));
    int l = 0, r = vec.back().first;
    while(l<=r){
        int mid = (l + r) >> 1;
        if(check(mid,vec)) r = mid - 1;
        else l = mid + 1;
    }
    cout << (l <= vec.back().first ? l : -1) << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

E. Chemistry in Berland

可以发现是一个树形结构,从下到上没用完的可以传上来继续用,不够用的就传上来再乘上倍数在上面分配

树形\(dp\)来做就好了,挺简单的

中间会爆\(long\ long\),用个\(long\ double\)来记一下

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 2e5+7;
vector<int> G[MAXN];
LL k[MAXN], A[MAXN], B[MAXN], tot;
int n, par[MAXN];
bool ok;
long double dfs(int u){
    long double s = B[u] - A[u];         // left
    for(int v : G[u]){
        long double x = dfs(v);
        if(x<=0){
            s += x * k[v];
            if(s+tot<0) ok = false;
        }
        else s += x;
    }
    return s;
}
void solve(){
    sci(n); ok = true;
    for(int i = 1; i <= n; i++) scl(B[i]), tot += B[i];
    for(int i = 1; i <= n; i++) scl(A[i]);
    for(int i = 2; i <= n; i++) sci(par[i]), scl(k[i]), G[par[i]] << i;
    long double ret = dfs(1);
    if(!ok or ret<0) cout << "NO" << endl;
    else cout << "YES" << endl;

}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

F. Random Query

找每个数在哪些区间出现过,然后统计一下,除以总区间数即可

可以考虑找每个数在哪些区间里没有出现,然后拿总区间数去减一下,记一下每个数出现的位置,没出现的区间数就是每两个出现的位置中间的那段长度的平方,挺水的

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define endl "\n"
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define pll pair<LL,LL>
#ifndef ONLINE_JUDGE
#define cout cerr
#endif
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x)  cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
template <typename T> vector<T>& operator << (vector<T> &__container, T x){ __container.push_back(x); return __container; }
template <typename T> ostream& operator << (ostream &out, vector<T> &__container){ for(T _ : __container) out << _ << ' '; return out; }
const int MAXN = 1e6+7;
vi pos[MAXN];

void solve(){
    int n; sci(n);
    vl A(n); for(auto &x : A) scl(x);
    for(int i = 0; i < n; i++) pos[A[i]] << i;
    LL tot = 0;
    for(int i = 1; i < MAXN; i++){
        if(pos[i].empty()) continue;
        pos[i] << n;
        int last = -1;
        LL sum = 1ll * n * n;
        for(int j = 0; j < (int)pos[i].size(); j++){
            sum -= 1ll * (pos[i][j] - last - 1) * (pos[i][j] - last - 1);
            last = pos[i][j];
        }
        tot += sum;
    }
    cout << fixed << setprecision(10) << 1. * tot / (1ll * n * n) << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}
posted @ 2020-08-25 00:52  _kiko  阅读(91)  评论(0编辑  收藏  举报