zoukankan      html  css  js  c++  java
  • 【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('
    ')
    #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,剩下的在转移时如果从一个可能有红球的盒子里转移过来则认为这个盒子里可能有红球

    #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('
    ')
    #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,那么不断删掉两端可以成立

    同时这也是必要的

    #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('
    ')
    #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会有一个生成树,就是每条边新建一个点,代表这个联通块,这个生成树的叶子是原来的节点

    然后二分最小的边,两个点同时找到树上的大于等于这条边的那个祖先

    如果相同的话看看这个子树里的值是否大于z,否则看看两个子树里的值是否大于z

    #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('
    ')
    #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

    有点神仙的博弈题

    就是把这些数从大到小排序,画出轮廓线,放到平面直角坐标系里,轮廓线上的点都是必胜态,轮廓线凸角的下面都是必败态,必败态的左和下是必胜态

    每个必败态会形成一个对角线,看看(0,0)在哪两个对角线之间,对角线相遇的地方是一个下凹的拐点,这个拐点是必胜态,看看0,0在这条线左边还是右边,左边就是左边的必败态控制,右边就是右边的必败态控制

    #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('
    ')
    #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,然后选择一种颜色填上

    要求补充不漏的话,我们必须要求这个颜色的第一个在之前一种颜色的前面

    只要用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('
    ')
    #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;
    }
    
  • 相关阅读:
    jQuery 基本选择器
    JavaScriptif while for switch流程控制 JS函数 内置对象
    JavaScrip基本语法
    数据库 存储引擎 表的操作 数值类型 时间类型 字符串类型 枚举集合 约束
    数据库基础知识 管理员 用户登录授权的操作
    粘包的产生原理 以及如何解决粘包问题
    socket TCP DPT 网络编程
    2018年年终总结
    Android技术分享
    No accelerator found
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10909915.html
Copyright © 2011-2022 走看看