• Codeforces Round #782 (Div. 2)


    CF1659A Red Versus Blue

    B 去均分 R,咋写都能过。

    CF1659B Bit Flipping

    可以看作,把每个元素都作了 \(k\) 遍操作。

    然后我们可以看作再做 \(k\) 遍操作,每次操作可以翻转一位。

    把全部变成 \(1\),剩下的操作全部累在最后一位,使它的负面影响最小。

    CF1659C Line Empire

    王国只能一次占领(但我感觉没有这个条件也只能这么做)。

    然后发现,一旦我占领了一个城市后我没有迁都,那么我再也不会迁都。简单计算推导可以证明这一点。

    然后枚举从哪个位置开始迁都就可以了。

    CF1659D Reverse Sort Sum

    constructive 的题目确实很有意思。

    宏观来看,发现对于每个位置先在一段时间里一直是 1 ,然后就一直都变成 0 了。

    不妨考虑一些简单的情况。对于第一个位置,注意到一旦出现一个 0,他就再也不会是 1,则 \(c_1\) 恰好是第一个出现 0 的位置。

    简单讨论发现 \(c_i\) 恰好就是第 \(i\)0 的位置(如果第 \(i\) 个位置是 1)。

    则,我们可以轻易一次确定每个位置的值。

    int c[MAXN] , a[MAXN];
     
    int main() {
    	int T;
    	read(T);
    	while(T -- > 0) {
    		int n;
    		read(n);
    		for (int i = 1; i <= n; ++i) read(c[i]) , a[i] = 1;
    		for (int i = 1; i <= n; ++i) {
    			if(a[i] && c[i]) {
    				a[c[i] + 1] = 0;
    				if(c[i] == n) break;
    			}
    			else {
    				a[c[i] + i] = 0;
    				if(c[i] + i > n) break;
    			}
    		}
    		for (int i = 1; i <= n; ++i) write(a[i] , ' ');
    		puts("");
    	}
    	return 0;
    }
    

    CF1659E AND-MEX Walk

    constructive 的确实比较有难度。

    求最小路径权值。优先判断能否找到权值为 0 的路径。因为是 mex 值,就是说我们能够找到一条至少同时包含一位的路径。

    然后判断能否为 1。假设不能为 1,即无论如何路径中都会出现 1,因此一定不会出现 2 ,否则必不可能出现 1

    因此现在问题只剩下如何判断能否不造出 1。那么就要求经过一条偶数边权,同时过程中必须要有其他位伴随 1 存在。

    预处理一下,从偶数边权的两端开始dp,计算每个点为起点能否得到这样的路径就好了。

    const int MAXN = 1e5 + 5;
     
    int f[35][MAXN] , n , m , chk[MAXN] , dp[MAXN][35];
    int findSet(int k , int x) {
    	if(f[k][x] != x) f[k][x] = findSet(k , f[k][x]);
    	return f[k][x];
    } 
     
    vector <pii> G[MAXN];
     
    struct Edge {
    	int u , v , w;
    }E[MAXN];
     
    void Union(int k , int u , int v) {
    	u = findSet(k , u) , v = findSet(k , v);
    	f[k][u] = f[k][v];
    	return;
    }
     
    int main() {
    	read(n),read(m);
    	for (int i = 1; i <= m; ++i) {
    		read(E[i].u),read(E[i].v),read(E[i].w);
    		G[E[i].u].push_back(mp(E[i].v , E[i].w));
    		G[E[i].v].push_back(mp(E[i].u , E[i].w));
    		if(!(E[i].w & 1)) {
    			chk[E[i].u] = chk[E[i].v] = 1;
    			for (int j = 1; j < 30; ++j) dp[E[i].u][j] = dp[E[i].v][j] = 1;
    		} 
    	}
    	
    	queue <pii> q;
    	for (int i = 1; i <= n; ++i) if(chk[i]) for (int j = 1; j < 30; ++j) q.push(mp(i , j));
    	
    	while(!q.empty()) {
    		int x = q.front().fs , y = q.front().sc;
    		q.pop();
    		for (auto v:G[x]) {
    			if((v.sc & 1) && (v.sc & (1 << y)) && !dp[v.fs][y]) {
    				q.push(mp(v.fs , y));
    				dp[v.fs][y] = 1;
    				chk[v.fs] = 1;
    			}
    		}
    	}
    	
    	for (int i = 0; i < 30; ++i) for (int j = 1; j <= n; ++j) f[i][j] = j;
    	
    	for (int i = 0; i < 30; ++i) {
    		int v = (1 << i);
    		for (int j = 1; j <= m; ++j) if(E[j].w & v) {
    			Union(i , E[j].u , E[j].v);
    		}
    	}
    	
    	
    	int Q;
    	read(Q);
    	while(Q -- > 0) {
    		int u , v;
    		read(u),read(v);
    		int fl = 0;
    		for (int i = 0; i < 30; ++i) {
    			if(findSet(i , u) == findSet(i , v)) {
    				fl = 1;
    				puts("0");
    				break;
    			}
    		}
    		if(fl) continue;
    		if(chk[u]) puts("1");
    		else puts("2");
    	}
    	
    	return 0;
    } 
    

    CF1659F Tree and Permutation Game

    在一棵树上,Alice 始终可以把我们的不在位的点变成两个,因为 Bob 最多只能影响两个位置。

    然后我可以很轻易地让他们靠在一起。然后,我可以让一个飞的很远,然后换到正确位置,然后棋子必须移动,但影响不到很远的位置,因此再换一次就好了。

    发现很远的要求就是直径达到 3。因此直径大于等于 3 的树 Alice 必胜。

    剩下一个菊花图的情况。

    分类讨论一下:

    1. 如果根节点不在位,并且棋子在根节点上,那 Bob 赢了。因为 Bob 只要保证根节点永远无法归位就好了。

    2. 如果根节点不在位,棋子在叶子上,那根节点必须一步到位。

    3. 如果根节点在位,棋子在根节点,发现至少交换次数为奇数就好了,因为任意一个棋子在根节点时,我们都剩奇数次,而到最后只会有两个数未归位,所以棋子在根节点时就可以直接一步归位。

    4. 如果根节点在位,棋子在叶子节点,下一步棋子必往根节点走,划归为 3情况即可。

    vector <int> G[MAXN];
    int n , p[MAXN] , deg[MAXN] , x , f[MAXN] , a[MAXN];
     
    int findSet(int x) {
    	if(f[x] != x) return f[x] = findSet(f[x]);
    	return f[x];
    }
     
    int main() {
    	int T;read(T);
    	while(T -- > 0) {
    		read(n),read(x);
    		for (int i = 1; i <= n; ++i) deg[i] = 0;
    		pii mx = mp(0 , 0);
    		for (int i = 1; i < n; ++i) {
    			int u , v;
    			read(u),read(v);
    			deg[u] ++ , deg[v] ++;
    		}
    		int fl = 1;
    		for (int i = 1; i <= n; ++i) read(a[i]) , p[a[i]] = i , mx = max(mx , mp(deg[i] , i)) , fl &= (p[i] == i);
    		int rt = mx.sc;
    		if(deg[rt] != n - 1 || fl) {
    			puts("Alice");
    			continue;
    		}
    		if(p[rt] != rt && (x == rt || p[x] == rt)) {
    			puts("Bob");
    			continue;
    		} 
    		else if(p[rt] != rt) {
    			for (int i = 1; i <= n; ++i) if(p[i] == rt) {
    				swap(p[i] , p[rt]);
    				break;
    			}
    			x = rt;
    		}
    		fl = 1;
    		for (int i = 1; i <= n; ++i) f[i] = i , fl &= (p[i] == i);
    		if(fl) {
    			puts("Alice");
    			continue;
    		}
    		for (int i = 1; i <= n; ++i) f[findSet(i)] = f[findSet(p[i])];
    		int num = n;
    		for (int i = 1; i <= n; ++i) if(findSet(i) == i) num --;
    		if(num == 1 && x != rt && p[x] == x) {
    			puts("Alice");
    			continue;
    		}
    		num += (x != rt);
    		if(num & 1) puts("Alice");
    		else puts("Bob");
    	}
    	return 0;
    } 
    
  • 相关阅读:
    LeetCode 116. Populating Next Right Pointers in Each Node
    redis复制
    redisLRU驱动事件(LRU eviction)
    Fetch API & arrayBuffer & Blob All In One
    Fetch API render ArrayBuffer to object URL in js All in One
    js object URL & data URL All In One
    TypeScript Decorator Metadata All In One
    Fetch API & HTTP Response opaque All In One
    Blob & readableStream All In One
    斯特鲁维测地弧 All In One
  • 原文地址:https://www.cnblogs.com/Reanap/p/16293679.html
Copyright © 2020-2023  润新知