【AtCoder】AGC008

AGC008

A - Simple Calculator

若是符號相同,那麼若是y比x大直接走,不然須要兩次反號node

若是符號不一樣,須要絕對值的差加一次反號c++

若是有一個是0,且y比x要小,那隻須要一次反號spa

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 5005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int64 x,y;
void Solve() {
    read(x);read(y);
    if(x * y >= 0) {
        if(y >= x) {out(y - x);enter;}
        else if(x * y != 0) {out(x - y + 2);enter;}
        else {out(x - y + 1);enter;}
    }
    else {
        out(abs(abs(x) - abs(y)) + 1);enter;
    }
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

B - Contiguous Repainting

合法的序列中必須有一段長度大於等於K的同色的段便可code

枚舉同色段的位置和它的顏色,只須要加上兩邊全部的正數便可排序

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N,K;
int64 pre[MAXN],suf[MAXN],a[MAXN],sum[MAXN];
void Solve() {
    read(N);read(K);

    for(int i = 1 ; i <= N ; ++i) {
        read(a[i]);
        sum[i] = sum[i - 1] + a[i];
        pre[i] = pre[i - 1];
        if(a[i] > 0) pre[i] = pre[i] + a[i];
    }
    for(int i = N ; i >= 1 ; --i) {
        suf[i] = suf[i + 1];
        if(a[i] > 0) suf[i] = suf[i] + a[i];
    }
    int64 ans = 0;
    for(int i = 1 ; i <= N ; ++i) {
        int r = i + K - 1;
        if(r > N) break;
        int64 all = pre[i - 1] + suf[r + 1];
        if(sum[r] - sum[i - 1] > 0) all += sum[r] - sum[i - 1];
        ans = max(ans,all);
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

C - Tetromino Tiling

簡單分析一下只有I,O,L,J是有用的rem

咱們先儘可能一個I,一個L,一個J拼成一個長度爲6的get

而後剩下的II兩兩組合,L兩兩組合,J兩兩組合it

若是I,J,L剩下的有兩個,且我拼過一個長度爲6的,那麼我把這個長度爲6的拆開分給這兩個class

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int64 aI,aO,aT,aJ,aL,aS,aZ;
int64 ans = 0;
void Solve() {
    read(aI);read(aO);read(aT);read(aJ);read(aL);read(aS);read(aZ);
    ans = aO;
    int64 t = min(aI,min(aJ,aL));
    ans += 3 * t;
    aI -= t;aJ -= t;aL -= t;
    ans += (aI / 2) * 2;aI %= 2;
    ans += (aJ / 2) * 2;aJ %= 2;
    ans += (aL / 2) * 2;aL %= 2;
    if(aI + aJ + aL >= 2) {
        if(t) {
            ans -= 3;ans += 4;
        }
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

D - K-th K

直接把這些位置排序,而後按照須要給位置最前且沒有知足的位置填須要的數date

而後若是一個位置過去了,咱們把它後面的數,例如第2個2填完了,咱們把N - 2個2扔進一個vector,vector裏面的數不在意順序,隨取隨用

若是沒有數用了也是不合法

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 505
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
int N;
int x[MAXN],id[MAXN];
int val[MAXN * MAXN];
bool vis[MAXN];
vector<int> r;
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
        read(x[i]);
        val[x[i]] = i;
        id[i] = i;
    }
    sort(id + 1,id + N + 1,[](int a,int b){return x[a] < x[b];});
    int p = 1,rem = id[1] - 1;
    vis[1] = 1;
    for(int i = 1 ; i <= N * N ; ++i) {
        if(val[i]) {
            if(!vis[val[i]]) {puts("No");return;}
            for(int j = 1 ; j <= N - val[i] ; ++j) r.pb(val[i]);
        }
        else {
            while(!rem && p < N) {++p;rem = id[p] - 1;}
            if(rem) {
                val[i] = id[p];
                --rem;
                if(!rem) vis[id[p]] = 1;
            }
            else {
                if(r.size() == 0) {puts("No");return;}
                val[i] = r.back();r.pop_back();
            }
        }
    }
    puts("Yes");
    for(int i = 1 ; i <= N * N ; ++i) {out(val[i]);space;}
    enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

E - Next or Nextnext

咱們直接建一張i->a[i]的圖,最後咱們用排列i->p[i]建出的圖至關於一次走一步或者一次走兩步

發現這是分開的不少基環內向樹,咱們分開算答案統計便可

若是有一個環,環上的某些點掛着鏈,鏈必須只是單鏈,不然就不合法

至關於往環上放點,若是一個點上掛着鏈,那麼這個點以前鏈長的邊都會被這個點佔據

咱們把佔據的都標記好了,發現這些佔據不重合的時候纔算合法

這個時候咱們看看這個點鏈長+1前位置的邊是否被佔據,若是沒有被佔據,這個點掛着的鏈在環上就有兩種填法

若是隻有一個環,沒有鏈

那麼奇數的環(1除外)能夠有兩種走法

並且兩個數量相同的環能夠拼成一個新環,這個環上每一個人到目標位置距離都是2

能夠用一個dp來計算相同點數的環的分配方案

把這些方案都乘起來就是總方案

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        res = res * 10 +c - '0';
        c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
const int MOD = 1000000007;
int N,head[MAXN],sumE;
int a[MAXN];
int deg[MAXN],line[MAXN];
bool vis[MAXN],mark[MAXN];
int cnt[MAXN],dp[MAXN],f[MAXN];
vector<int> v;
int inc(int a,int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
    return 1LL * a * b % MOD;
}
void update(int &x,int y) {
    x = inc(x,y);
}
queue<int> Q;
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) {
        read(a[i]);
        ++deg[a[i]];
    }
    for(int i = 1 ; i <= N ; ++i) {
        if(!deg[i]) Q.push(i);
    }
    while(!Q.empty()) {
        int u = Q.front();Q.pop();
        vis[u] = 1;
        if(line[a[u]]) {puts("0");return;}
        line[a[u]] = line[u] + 1;
        if(!(--deg[a[u]])) Q.push(a[u]);
    }
    int ans = 1;
    for(int i = 1 ; i <= N ; ++i) {
        if(!vis[i]) {
            v.clear();
            int p = i;v.pb(i);vis[p] = 1;p = a[p];
            while(p != i) {
                vis[p] = 1;
                v.pb(p);
                p = a[p];

            }
            int n = v.size();
            bool no = 1;
            for(int j = 0 ; j < n ; ++j) {
                mark[j] = 0;
                if(line[v[j]]) no = 0;
            }
            if(no) {cnt[n]++;continue;}
            for(int j = 0 ; j < n ; ++j) {
                for(int k = 0 ; k < line[v[j]] ; ++k) {
                    int t = ((j - k) % n + n) % n;
                    if(mark[t]) {puts("0");return;}
                    mark[t] = 1;
                }
            }
            for(int j = 0 ; j < n ; ++j) {
                if(!line[v[j]]) continue;
                int t = ((j - line[v[j]]) % n + n) % n;
                if(!mark[t]) ans = mul(ans,2);
            }
        }
    }
    for(int i = 1 ; i <= N ; ++i) {
        if(cnt[i]) {
            for(int j = 1 ; j <= cnt[i] ; ++j) dp[j] = 0;
            dp[0] = 1;
            for(int j = 1 ; j <= cnt[i] ; ++j) {
                dp[j] = dp[j - 1];
                if((i & 1) && i != 1) update(dp[j],dp[j - 1]);
                if(j >= 2) {
                    update(dp[j],mul(j - 1,mul(i,dp[j - 2])));
                }
            }
            ans = mul(ans,dp[cnt[i]]);
        }
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

F - Black Radius

1300分的話,若是\(f(x,d)\)即從x點延伸d長度不爲全集,那麼若是d能夠更小,咱們就不統計,也就是附近有個點\(f(y,d - 1)\)和它覆蓋的是同樣的

這個能夠用x當根每一個兒子最大深度統計出來,就是兩次樹dp

把這個最大的d記作\(high[x]\)

而後咱們對於每一個點記錄一個\(low[x]\)表示最小能從哪一個點往上延伸

咱們在求high的時候會發現每一個點和它當根的時候深度最大的那個兒子可能有一個low上的轉移關係,咱們記錄下來

而後咱們high從小到大枚舉每一個點,若是這個點是偏心點,那麼low是0,若是這個點low <= high,就證實這個點大於low的時候已是偏心點同樣了,能夠更新周圍的點,利用咱們求的轉移關係而後更新周圍點便可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
template<class T>
void read(T &res) {
    res = 0;T f = 1;char c = getchar();
    while(c < '0' || c > '9') {
    if(c == '-') f = -1;
    c = getchar();
    }
    while(c >= '0' && c <= '9') {
    res = res * 10 +c - '0';
    c = getchar();
    }
    res *= f;
}
template<class T>
void out(T x) {
    if(x < 0) {x = -x;putchar('-');}
    if(x >= 10) {
    out(x / 10);
    }
    putchar('0' + x % 10);
}
struct node {
    int to,next;
}E[MAXN * 2];
int N,head[MAXN],sumE,dep[MAXN],fr[MAXN],high[MAXN],low[MAXN];
char s[MAXN];
vector<int> rec[MAXN];
vector<pii > to[MAXN];
void add(int u,int v) {
    E[++sumE].to = v;
    E[sumE].next = head[u];
    head[u] = sumE;
}
void dfs1(int u,int fa) {
    for(int i = head[u] ; i ; i = E[i].next) {
    int v = E[i].to;
    if(v != fa) {
        dfs1(v,u);
        dep[u] = max(dep[u],dep[v] + 1);
    }
    }
}
void dfs2(int u,int fa) {
    vector<pii > vec;
    dep[u] = max(dep[u],fr[u] + 1);
    vec.pb(mp(1,u));
    if(fa) vec.pb(mp(fr[u] + 2,fa));
    pii p = mp(0,0);
    for(int i = head[u] ; i ; i = E[i].next) {
    int v = E[i].to;
    if(v != fa) {
        vec.pb(mp(dep[v] + 2,v));
        if(dep[v] > dep[p.se]) p.se = v;
        if(dep[p.se] > dep[p.fi]) swap(p.fi,p.se);
    }
    }
    sort(vec.begin(),vec.end());
    high[u] = dep[u] - 1;
    int s = vec.size() - 1;
    high[u] = min(high[u],vec[s - 1].fi);
    if(high[u] < dep[u] - 1){
    to[u].pb(mp(vec[s].se,high[u]));
    }
    vec.clear();
    for(int i = head[u] ; i ; i = E[i].next) {
    int v = E[i].to;
    if(v != fa) {
        fr[v] = max(fr[v],fr[u] + 1);
        if(v != p.fi) fr[v] = max(fr[v],dep[p.fi] + 1);
        if(v != p.se) fr[v] = max(fr[v],dep[p.se] + 1);
    }
    }
    for(int i = head[u] ; i ; i = E[i].next) {
    int v = E[i].to;
    if(v != fa) {
        dfs2(v,u);
    }
    }
}
void Solve() {
    read(N);
    int a,b;
    for(int i = 1 ; i < N ; ++i) {
    read(a);read(b);add(a,b);add(b,a);
    }
    scanf("%s",s + 1);
    dep[0] = -1;fr[1] = -1;
    dfs1(1,0);dfs2(1,0);
    for(int i = 1 ; i <= N ; ++i) {
    rec[high[i]].pb(i);
    low[i] = high[i] + 1;
    }
    for(int i = 0 ; i <= N ; ++i) {
    for(auto v : rec[i]) {
        if(s[v] == '1') {
        low[v] = 0;
        }
        if(low[v] <= high[v]){
        for(auto k : to[v]) {
            low[k.fi] = min(low[k.fi],k.se);
        }
        }
    }
    }
    int64 ans = 1;
    for(int i = 1 ; i <= N ; ++i) {
    ans += high[i] - low[i] + 1;
    }
    out(ans);enter;
}
int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
相關文章
相關標籤/搜索