• 【AtCoder】AGC012


    AGC012

    A - AtCoder Group Contest

    从最后开始间隔着取就行

    #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 * 3];
    void Solve() {
        read(N);
        for(int i = 1 ; i <= 3 * N ; ++i) read(a[i]);
        sort(a + 1,a + 3 * N + 1);
        int64 ans = 0;
        for(int i = 3 * N - 1 ; i >= N + 1 ; i -= 2) {
    	ans += a[i];
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    B - Splatter Painting

    大意:有一张图,每个操作是把从v开始距离不超过d的点染成c,求每个点最后的颜色,d<=10

    每个点拆成10个,表示从第i个点出发能延伸j长度的询问标号最大的颜色

    从后往前处理颜色,遇到不能更新的停止即可

    复杂度(O(dN + M))

    #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);
    }
    struct node {
        int to,next;
    }E[MAXN * 2];
    int head[MAXN],sumE;
    int N,M,Q;
    int dp[MAXN][11];
    int c[MAXN],d[MAXN],v[MAXN];
    void add(int u,int v) {
        E[++sumE].to = v;E[sumE].next = head[u];head[u] = sumE;
    }
    void dfs(int v,int d) {
        if(!d) return;
        for(int i = head[v] ; i ; i = E[i].next) {
    	int t = E[i].to;
    	if(dp[t][d - 1] < dp[v][d]) {
    	    dp[t][d - 1] = dp[v][d];
    	    dfs(t,d - 1);
    	}
        }
    }
    void Solve() {
        read(N);read(M);
        int a,b;
        for(int i = 1 ; i <= M ; ++i) {
    	read(a);read(b);
    	add(a,b);add(b,a);
        }
        read(Q);
        for(int i = 1 ; i <= Q ; ++i) {
    	read(v[i]);read(d[i]);read(c[i]);
        }
        for(int i = Q ; i >= 1 ; --i) {
    	if(dp[v[i]][d[i]] < i) {
    	    dp[v[i]][d[i]] = i;
    	    dfs(v[i],d[i]);
    	}
        }
        for(int i = 1 ; i <= N ; ++i) {
    	int g = 0;
    	for(int j = 0 ; j <= 10 ; ++j) {
    	    g = max(g,dp[i][j]);
    	}
    	out(c[g]);enter;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    C - Tautonym Puzzle

    大意:构造一个字符串s长度不超过200,字符集不超过100,要求s的子序列中满足能长度为偶数,前一半字符串和后一半相同的个数正好为N

    有点神仙的一道题

    就是扔一个1,2,3,4,5,6...N在后面,前面构造一个序列使得最长上升序列为给定值即可

    我们发现构造一个最长上升序列时,把最大值扔在前面可以+1,扔在最后可以乘2

    那么N只要80左右,总长度是160左右就可以构出来了

    #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);
    }
    vector<int> p;
    int64 N;
    void Solve() {
        read(N);
        int num = 0,t;
        ++N;
        for(int i = 40 ; i >= 0 ; --i) {
    	if((N >> i) & 1) {
    	    t = i;
    	    break;
    	}
        }
        for(int i = t - 1 ; i >= 0 ; --i) {
    	++num;
    	p.pb(num);
    	if((N >> i) & 1) {
    	    ++num;
    	    p.insert(p.begin(),num);
    	}
        }
        t = p.size();
        for(int i = 1 ; i <= t ; ++i) p.pb(i);
        out(p.size());enter;
        for(auto a : p) {
    	out(a);space;
        }
        enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    D - Colorful Balls

    大意:每次选两个相同颜色的球价值总和不超过X,或两个不同颜色的球价值不超过Y,可以交换位置,求不同的颜色序列数

    可以把每个点如果能连到同颜色最小点,就和同颜色最小点的并查集连起来

    否则如果已经是同颜色最小点或者和同颜色最小点无法连,就和异颜色最小点连起来

    只需要处理出价值最小且颜色不同的前两个点即可

    之后选出价值最小的那个点的集合(因为若颜色可以交换则一定和它在一个集合)用可重全排列的式子算一下即可

    #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 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);
    }
    const int MOD = 1000000007;
    int fac[MAXN],invfac[MAXN],N,X,Y;
    int vp[MAXN],fa[MAXN],id[MAXN];
    pii c[MAXN];
    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 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;
    }
    int getfa(int x) {
        return fa[x] == x ? x : fa[x] = getfa(fa[x]);
    }
    void Solve() {
        read(N);read(X);read(Y);
        for(int i = 1 ; i <= N ; ++i) {
            read(c[i].se);read(c[i].fi);
        }
        sort(c + 1,c + N + 1);
        int sec = 2;
        while(sec <= N && c[sec].se == c[1].se) ++sec;
        if(sec > N) {puts("1");return;}
        for(int i = N ; i >= 1 ; --i) {
            vp[c[i].se] = i;
            fa[i] = i;
        }
        for(int i = N ; i >= 1 ; --i) {
            if(i != vp[c[i].se] && c[i].fi + c[vp[c[i].se]].fi <= X) {
                fa[getfa(i)] = getfa(vp[c[i].se]);
            }
            else if(c[i].se != c[1].se && c[i].fi + c[1].fi <= Y) {
                fa[getfa(i)] = getfa(1);
            }
            else if(c[i].se != c[sec].se && c[i].fi + c[sec].fi <= Y) {
                fa[getfa(i)] = getfa(sec);
            }
        }
        fac[0] = 1;
        for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i);
        invfac[N] = fpow(fac[N],MOD - 2);
        for(int i = N - 1 ; i >= 0 ; --i) invfac[i] = mul(invfac[i + 1],i + 1);
        int siz = 0;
        for(int i = 1 ; i <= N ; ++i) {
            if(getfa(i) == getfa(1)) {
                id[c[i].se]++;
                ++siz;
            }
        }
        int ans = fac[siz];
        for(int i = 1 ; i <= N; ++i) {
            ans = mul(ans,invfac[id[i]]);
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    E - Camel and Oases

    大意:有n个绿洲排成一排,骆驼能装V的水,最多只能走V的路,或者跳一步到任一点,但是容量变成(lfloor frac{V}{2} floor),已经储存的水变为0,到了一个绿洲可以吸水,一个绿洲可以吸任意多次的水,问从某个绿洲出发能否遍历所有绿洲

    我们显然有(log V)种不同的容量,也就是当我们选择了一块区间(这个区间里的点两两距离不超过V,且至多只有logV个区间否则一定impossible)

    对于每次容量时,我可以选择这个容量在区间左边用还是右边用,分别是前缀和后缀

    于是我们对于前缀dp一个dp[S]表示用了S这个集合的容量,最远可以走遍的前缀是dp[S],后缀同理

    于是只需要求出来一个S,(dpL[S] >= l - 1)并且(dpR[All otimes S] <= r + 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 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);
    }
    int N,V;
    int x[MAXN],d[30],tot,r[30][MAXN],l[30][MAXN];
    int dp[2][(1 << 19) + 5];
    void Solve() {
        read(N);read(V);
        for(int i = 1 ; i <= N ; ++i) read(x[i]);
        d[0] = V / 2;
        while(d[tot]) {
    	++tot;
    	d[tot] = d[tot - 1] / 2;
        }
        for(int j = 0 ; j <= tot ; ++j) {
    	r[j][N] = N;r[j][N + 1] = N + 1;
    	for(int i = N - 1 ; i >= 1 ; --i) {
    	    r[j][i] = i;
    	    if(x[i + 1] - x[i] <= d[j]) r[j][i] = r[j][i + 1];
    	}
    	l[j][1] = 1;
    	for(int i = 2 ; i <= N ; ++i) {
    	    l[j][i] = i;
    	    if(x[i] - x[i - 1] <= d[j]) l[j][i] = l[j][i - 1];
    	}
        }
        dp[0][0] = 0;dp[1][0] = N + 1;
        for(int S = 1 ; S < (1 << (tot + 1)) ; ++S) {
    	dp[1][S] = N + 1;
    	for(int j = 0 ; j <= tot ; ++j) {
    	    if(S >> j & 1) {
    		dp[0][S] = max(r[j][dp[0][S ^ (1 << j)] + 1],dp[0][S]);
    		dp[1][S] = min(l[j][dp[1][S ^ (1 << j)] - 1],dp[1][S]);
    	    }
    	}
        }
        int cnt = 0;
        for(int i = 1 ; i <= N ; ++i) {
    	int l = i,r = i;
    	while(r < N && x[r + 1] - x[r] <= V) ++r;
    	i = r;
    	++cnt;
        }
        if(cnt - 1 > tot + 1) {
    	for(int i = 1 ; i <= N ; ++i) {
    	    puts("Impossible");
    	}
    	return;
        }
        for(int i = 1 ; i <= N ; ++i) {
    	int l = i,r = i;
    	while(r < N && x[r + 1] - x[r] <= V) ++r;
    	int A = (1 << tot + 1) - 1;
    	bool f = 0;
    	for(int S = 0 ; S < (1 << tot + 1) ; ++S) {
    	    if(dp[0][S] >= l - 1 && dp[1][A ^ S] <= r + 1) {f = 1;break;}
    	}
    	for(int i = l ; i <= r ; ++i) {
    	    if(f) puts("Possible");
    	    else puts("Impossible");
    	}
    	i = r;
        }
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    

    F - Prefix Median

    大意:2×N- 1个数,可以重排,每次拿前2×i - 1的中位数作为(b_{i}),求不同的(b_{i})的个数

    从后往前数,最后一个肯定是全局中位数

    事实上我们的选择需要满足第一个数在中间1个,第二个数在中间3个中,第三个数在中间5个中,数可以重复选择

    还有要满足的就是不存在((i < j) B_{j} < B_{i} < B_{j + 1})或者((i < j) B_j > B_{i} > B_{j + 1})

    这是必要的,可以证明这是充分的

    也就是我们对于(B_{1},B_{2}...B_{n})满足这些条件,就一定可以被构造出来

    从后往前构造

    (B_{N})固定了

    我们要选择(B_{i})的时候,如果(B_{i})(B_{i + 1})一样,我们就删掉左边未出现的数最大的,和右边未出现的数最小的

    如果(B_{i} < B_{i + 1})那么我们删掉(B_1....B_{i - 1})中在右边未出现的最小的两个

    最后一种情况同理

    这样的话也就是已经存在的值域中选左右的两部分,不能选值域非端点的中间

    dp状态是(dp[i][j][k])表示从后往前填到第i个数,值域有j个数,当前数是第k个

    #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 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);
    }
    const int MOD = 1000000007;
    int N;
    int dp[55][105][105];
    int a[105],id[MAXN],tot;
    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);
    }
    void Solve() {
        read(N);
        for(int i = 1 ; i <= 2 * N - 1 ; ++i) read(a[i]);
        sort(a + 1,a + 2 * N);
        dp[1][1][1] = 1;
        for(int i = 1 ; i < N ; ++i) {
    	for(int j = 1 ; j <= 2 * N - 1 ; ++j) {
    	    for(int h = 1 ; h <= j ; ++h) {
    		int tj = j,th = h;
    		if(a[N + i] != a[N + i - 1]) ++tj;
    		if(a[N - i] != a[N - i + 1]) ++tj,++th;
    		for(int k = 1 ; k <= tj ; ++k) {
    		    if(k < th)
    			update(dp[i + 1][k + tj - th + 1][k],dp[i][j][h]);
    		    else if(k > th)
    			update(dp[i + 1][th + tj - k + 1][th + 1],dp[i][j][h]);
    		    else if(k == th) 
    			update(dp[i + 1][tj][th],dp[i][j][h]);
    		}
    	    }
    	}
        }
        int ans = 0;
        for(int j = 1 ; j <= 2 * N - 1 ; ++j) {
    	for(int h = 1 ; h <= j ; ++h) {
    	    update(ans,dp[N][j][h]);
    	}
        }
        out(ans);enter;
    }
    int main() {
    #ifdef ivorysi
        freopen("f1.in","r",stdin);
    #endif
        Solve();
    }
    
  • 相关阅读:
    资源合并fis-postpackager-simple插件的使用
    FIS3使用官方例子流程
    FIS常用命令
    SASS输出风格
    Webstorm实时编译SASS和LESS
    如何使用Less?
    DNS预解析dns-prefetch提升页面载入速度优化前端性能
    前端性能优化策略
    利用多域名存储静态资源进行性能优化:网站的静态资源为什么要使用独立域名
    Nginx多域名配置
  • 原文地址:https://www.cnblogs.com/ivorysi/p/10794939.html
Copyright © 2020-2023  润新知