【AtCoder】AGC002

AGC002

A - Range Product

#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);
}
int a,b;
void Solve() {
    read(a);read(b);
    if(b >= 0 && a <= 0) puts("Zero");
    else if(a > 0) {
    puts("Positive");
    }
    else {
    if((b - a + 1) & 1) puts("Negative");
    else puts("Positive");
    }
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

B - Box and Ball

若是一個地方的球空了把可能有紅球標成0,剩下的在轉移時若是從一個可能有紅球的盒子裏轉移過來則認爲這個盒子裏可能有紅球c++

#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,M,ct[MAXN],cnt[MAXN];
void Solve() {
    read(N);read(M);
    for(int i = 1 ; i <= N ; ++i) cnt[i] = 1;
    ct[1] = 1;
    int x,y;
    for(int i = 1 ; i <= M ; ++i) {
    read(x);read(y);
    cnt[x]--;cnt[y]++;
    if(ct[x]) {
        ct[y] = 1;
    }
    if(cnt[x] == 0) ct[x] = 0;
    }
    int ans = 0;
    for(int i = 1 ; i <= N ; ++i) {
    ans += ct[i];
    }
    out(ans);enter;
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

C - Knot Puzzle

若是存在兩端相鄰的相加大於等於L,那麼不斷刪掉兩端能夠成立優化

同時這也是必要的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 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,a[MAXN];
int64 L,sum;
vector<int> ans;
void Solve() {
    read(N);read(L);
    for(int i = 1 ; i <= N ; ++i) {read(a[i]);}
    for(int i = 1 ; i < N ; ++i) {
    if(a[i] + a[i + 1] >= L) {
        puts("Possible");
        for(int j = 1 ; j < i ; ++j) ans.pb(j);
        for(int j = N - 1 ; j > i ; --j) ans.pb(j);
        ans.pb(i);
        for(auto t : ans) {
        out(t);enter;
        }
        return;
    }
    }
    puts("Impossible");
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

D - Stamp Rally

kruskal會有一個生成樹,就是每條邊新建一個點,表明這個聯通塊,這個生成樹的葉子是原來的節點code

而後二分最小的邊,兩個點同時找到樹上的大於等於這條邊的那個祖先排序

若是相同的話看看這個子樹裏的值是否大於z,不然看看兩個子樹裏的值是否大於zget

#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 400005
//#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 Ncnt,N,M,head[MAXN],sumE,Q;
int bel[MAXN],val[MAXN],siz[MAXN],fa[MAXN][20];
vector<int> to[MAXN];
int getfa(int x) {
    return bel[x] == x ? x : bel[x] = getfa(bel[x]);
}
void dfs(int u) {
    if(u <= N) siz[u]++;
    for(auto t : to[u]) {
    fa[t][0] = u;
    dfs(t);
    siz[u] += siz[t];
    }
    
}
void Solve() {
    read(N);read(M);
    Ncnt = N;
    int a,b;
    for(int i = 1 ; i <= N + M ; ++i) bel[i] = i;
    for(int i = 1 ; i <= M ; ++i) {
    read(a);read(b);
    if(getfa(a) != getfa(b)) {
        ++Ncnt;
        to[Ncnt].pb(getfa(a));to[Ncnt].pb(getfa(b));
        bel[getfa(a)] = Ncnt;
        bel[getfa(b)] = Ncnt;
        val[Ncnt] = i;
    }
    }
    dfs(Ncnt);
    for(int j = 1 ; j <= 19 ; ++j) {
    for(int i = 1 ; i <= Ncnt ; ++i) {
        fa[i][j] = fa[fa[i][j - 1]][j - 1];
    }
    }
    read(Q);
    int x,y,z;
    val[0] = M + 1;
    for(int i = 1 ; i <= Q ; ++i) {
    read(x);read(y);read(z);
    int L = 1,R = M;
    while(L < R) {
        int a = x,b = y;
        int mid = (L + R) >> 1;
        for(int j = 19 ; j >= 0 ; --j) {
        if(val[fa[a][j]] <= mid) a = fa[a][j];
        if(val[fa[b][j]] <= mid) b = fa[b][j];
        }
        int res = 0;
        if(a == b) res += siz[a];
        else res += siz[a] + siz[b];
        if(res >= z) R = mid;
        else L = mid + 1;
    }
    out(L);enter;
    }
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

E - Candy Piles

有點神仙的博弈題it

就是把這些數從大到小排序,畫出輪廓線,放到平面直角座標系裏,輪廓線上的點都是必勝態,輪廓線凸角的下面都是必敗態,必敗態的左和下是必勝態class

每一個必敗態會造成一個對角線,看看(0,0)在哪兩個對角線之間,對角線相遇的地方是一個下凹的拐點,這個拐點是必勝態,看看0,0在這條線左邊仍是右邊,左邊就是左邊的必敗態控制,右邊就是右邊的必敗態控制date

#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;
int a[MAXN];
vector<pii > p;
void Solve() {
    read(N);
    for(int i = 1 ; i <= N ; ++i) read(a[i]);
    sort(a + 1,a + N + 1,[](int c,int d){return c > d;});
    for(int i = 1 ; i <= N ; ++i) {
    if(a[i + 1] != a[i]) {
        p.pb(mp(i,i - a[i]));
    }
    }
    int c = -1,d = p.size();
    
    while(c < (int)p.size() - 1 && p[c + 1].se <= 0) ++c;
    while(d > 0 && p[d - 1].se >= 0) --d;
    if(c >= 0) {
    if(p[c].se == 0) {puts("Second");return;}
    }
    bool f = 0;
    if(c >= 0 && d < (int)p.size()) {
    if(!((abs(p[c].se) ^ abs(p[d].se)) & 1)) {
        f = (abs(p[c].se) & 1);
    }
    else {
        int t = p[c].fi - a[p[c].fi + 1];
        if(t == 0) f = 1;
        else if(0 < t) {f |= abs(p[c].se) & 1;}
        else f |= abs(p[d].se) & 1;
    }
    }
    else if(c >= 0) { f |= abs(p[c].se) & 1;}
    else if(d < (int)p.size()) {f |= p[d].se & 1;}
    if(f) puts("First");
    else puts("Second");
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}

F - Leftmost Ball

倒着作就好了,每次在隊首新加一個0,而後選擇一種顏色填上gc

要求補充不漏的話,咱們必需要求這個顏色的第一個在以前一種顏色的前面

只要用dp記錄一下前一個顏色的位置就能夠了

狀態是\(n^2\)的的,用前綴和優化一下轉移是\(O(1)\)的,能夠經過

#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 fac[10000005],invfac[10000005];
int dp[2005][2005],N,K,sum[2005];
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);
}
int C(int n,int m) {
    if(n < m) return 0;
    return mul(fac[n],mul(invfac[m],invfac[n - m]));
}
int Query(int n,int m) {
    return C(n + m - 1,m - 1);
}
int fpow(int x,int c) {
    int res = 1,t = x;
    while(c) {
    if(c & 1) res = mul(res,t);
    t = mul(t,t);
    c >>= 1;
    }
    return res;
}
void Solve() {
    read(N);read(K);
    if(K == 1) {puts("1");return;}
    fac[0] = 1;
    for(int i = 1 ; i <= 10000000 ; ++i) fac[i] = mul(fac[i - 1],i);
    invfac[10000000] = fpow(fac[10000000],MOD - 2);
    for(int i = 9999999 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
    dp[1][0] = 1;
    for(int i = 2 ; i <= N ; ++i) {
    int t = (i - 1) * K + 1;
    for(int j = N ; j >= 0 ; --j) sum[j] = inc(sum[j + 1],dp[i - 1][j]);
    for(int j = 0 ; j <= i ; ++j) {
        update(dp[i][j],mul(sum[max(0,j - 1)],Query(K - 2,t - j)));
    }
    }
    int ans = 0;
    for(int j = 0 ; j <= N ; ++j) update(ans,mul(dp[N][j],fac[N]));
    out(ans);enter;
}

int main() {
#ifdef ivorysi
    freopen("f1.in","r",stdin);
#endif
    Solve();
    return 0;
}
相關文章
相關標籤/搜索