Educational Codeforces Round 33

Educational Codeforces Round 33 

A. Chess For Three

模拟

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;

bool check(int x, int y, vi &A){
    for(int &z : A){
        int w = 0;
        for(int i = 1; i <= 3; i++) if(i!=x and i!=y) w = i;
        if(z==x) y = w;
        else if(z==y) x = w;
        else return false;
    }
    return true;
}

void solve(){
    int n; sci(n);
    vi A(n); for(int &x : A) sci(x);
    if(!check(1,2,A)) 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;
}

B. Beautiful Divisors

枚举因子判断

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;

bool check(int x){
    vi A;
    while(x){
        A << x % 2;
        x >>= 1;
    }
    int ptr = 0;
    while(A[ptr]==0) ptr++;
    for(int j = ptr; j < A.size(); j++) if(A[j]==0) return false;
    return ptr * 2  + 1 == A.size();
}

void solve(){
    int n; sci(n);
    vi div;
    for(int i = 1; i * i <= n; i++){
        if(n%i!=0) continue;
        div << i;
        if(i!=n/i) div << n / i;
    }
    sort(all(div),greater<int>());
    for(int &d : div) if(check(d)){
        cout << d << endl;
        return;
    }
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

C. Rumor

并查集,同时维护并查集中的最小值,最后把每个集合中的最小值加起来即可

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, w[MAXN], f[MAXN];
int findx(int x){ return x == f[x] ? x : f[x] = findx(f[x]); }
void merge(int u, int v){
    int x = findx(u), y = findx(v);
    int ww = min(w[x], w[y]);
    f[x] = y;
    w[y] = ww;
}
void solve(){
    sci(n); sci(m);
    for(int i = 1; i <= n; i++) sci(w[i]);
    for(int i = 1; i <= n; i++) f[i] = i;
    for(int i = 1; i <= m; i++){
        int u, v;
        sci(u); sci(v);
        if(findx(u) == findx(v)) continue;
        merge(u,v);
    }
    LL ret = 0;
    for(int i = 1; i <= n; i++) if(i==findx(i)) ret += w[i];
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

D. Credit Card

每次遇到\(0\)的时候先判断能否在之前的时候就加上

具体做法就是每次遇到\(0\)之后维护一个钱的最大值,只要保证在之前就把钱加上之后也不会超过限制就在之前把钱加上

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, d;
    sci(n); sci(d);
    vi A(n); for(int &x : A) sci(x);
    int cnt = 0;
    int curmoney = 0;
    int maxmoney = 1e9+7;
    for(int i = 0; i < n; i++){
        if(A[i]==0){
            if(curmoney>=0) continue;
            if(d - maxmoney >= -curmoney){
                maxmoney -= curmoney;
                curmoney = 0;
            }else{
                maxmoney = curmoney = 0;
                cnt++;
            }
        }else{
            if(curmoney + A[i] > d){
                cout << -1 << endl;
                return;
            }
            curmoney += A[i];
            cmax(maxmoney,curmoney);
        }
    }
    cout << cnt << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}

E. Counting Arrays

先不管正负

分解质因子,然后每个质因子有若干次,把每个质因子分配到\(y\)个位置上去,假设某个质因子出现了\(a\)次,那么对于这个质因子的方案数就是\(\tbinom{y+a-1}{y-1}\)

\(y-1\)个数的正负可以随便分,最后一个来决定正负即可,所以正负号的分配有\(2^{y-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 = 2e6+7;
const int MOD = 1e9+7;
int fac[MAXN], inv[MAXN], rfac[MAXN], pw[MAXN];
int C(int n, int m){ return n<m ? 0 : 1ll * fac[n] * rfac[m] % MOD * rfac[n-m] % MOD; }

void solve(){
    int x, y; sci(x); sci(y);
    vector<pii> vec;
    for(int i = 2; i * i <= x; i++){
        if(x%i!=0) continue;
        vec << make_pair(i,0);
        while(x%i==0) vec.back().second++, x /= i;
    }
    if(x!=1) vec << make_pair(x,1);
    LL ret = 1;
    for(auto p : vec) ret = 1ll * ret * C(y+p.second-1,y-1) % MOD;
    ret = 1ll * ret * pw[y-1] % MOD;
    cout << ret << endl;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    fac[0] = rfac[0] = inv[1] = pw[0] = 1;
    for(int i = 1; i < MAXN; i++) pw[i] = pw[i-1] * 2 % MOD;
    for(int i = 1; i < MAXN; i++) fac[i] = 1ll * fac[i-1] * i % MOD;
    for(int i = 2; i < MAXN; i++) inv[i] = 1ll * (MOD - MOD / i) * inv[MOD%i] % MOD;
    for(int i = 1; i < MAXN; i++) rfac[i] = 1ll * rfac[i-1] * inv[i] % MOD;
    int tt; for(sci(tt); tt--; solve());
    return 0;
}

F. Subtree Minimum 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 = 2e5+7;
int n, r, dep[MAXN], q, w[MAXN];
vi G[MAXN];

struct SegmentTree{
    int root[MAXN], ls[MAXN<<5], rs[MAXN<<5], minn[MAXN<<5], tot;
    void modify(int l, int r, int pos, int x, int &rt){
        rt = ++tot;
        minn[rt] = x;
        if(l+1==r) return;
        int mid = (l + r) >> 1;
        if(pos < mid) modify(l,mid,pos,x,ls[rt]);
        else modify(mid,r,pos,x,rs[rt]);
    }
    int merge(int u, int v, int l, int r){
        if(!u or !v) return u^v;
        if(l+1==r){
            int rt = ++tot;
            minn[rt] = min(minn[u],minn[v]);
            return rt;
        }
        int rt = ++tot;
        minn[rt] = INF;
        int mid = (l + r) >> 1;
        ls[rt] = merge(ls[u],ls[v],l,mid);
        rs[rt] = merge(rs[u],rs[v],mid,r);
        if(ls[rt]) cmin(minn[rt],minn[ls[rt]]);
        if(rs[rt]) cmin(minn[rt],minn[rs[rt]]);
        return rt;
    }
    int qmin(int rt, int l, int r, int L, int R){
        if(L>=r or l>=R or !rt) return INF;
        if(L<=l and r<=R) return minn[rt];
        int mid = (l + r) >> 1;
        return min(qmin(ls[rt],l,mid,L,R),qmin(rs[rt],mid,r,L,R));
    }
}ST;
void dfs(int u, int par){
    dep[u] = dep[par] + 1;
    ST.modify(1,n+1,dep[u],w[u],ST.root[u]);
    for(int v : G[u]){
        if(v==par) continue;
        dfs(v,u);
        ST.root[u] = ST.merge(ST.root[u],ST.root[v],1,n+1);
    }
}

void solve(){
    sci(n); sci(r);
    for(int i = 1; i <= n; i++) sci(w[i]);
    for(int i = 1; i < n; i++){
        int u, v; sci(u); sci(v);
        G[u] << v; G[v] << u;
    }
    dfs(r,0);
    sci(q);
    int lastans = 0;
    while(q--){
        int x, k;
        sci(x); sci(k);
        x = (x + lastans) % n + 1;
        k = (k + lastans) % n;
        cmin(k,n-dep[x]);
        printf("%d\n",lastans = ST.qmin(ST.root[x],1,n+1,dep[x],dep[x]+k+1));
    }
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("Local.in","r",stdin);
    freopen("ans.out","w",stdout);
    #endif
    solve();
    return 0;
}
posted @ 2020-08-27 22:45  _kiko  阅读(119)  评论(0编辑  收藏  举报