Educational Codeforces Round 125

CF1657A Integer Moves

要么走曼哈顿,要么不用走,要么一步到位。

CF1657B XY Sequence

能加就加,不能加再减,明显最优。

CF1567C Bracket Sequence Deletion

开头为 ( ,则下一个无论是啥都能删。

开头为 ')' ,且完全不能删当且仅当后面全是 ( ,因为一旦再出现 ) 就回文了。

CF1567D For Gamers. By Gamers.

卡了好久,我果然菜。。。

注意到我们只能使用一种兵种,设 \(i\) 兵种用了 \(x_i\) 个,则能杀死 boss 当且仅当 \(DH < h_id_ix_i\)

则发现只与兵种属性有关, \(n \ln n\) dp 算出用 \(x\) 的钱属性最高有多高就完了。

const int MAXN = 3e5 + 5;
const int MAXC = 1e6 + 5;
 
LL n , C , c[MAXN] , d[MAXN] , h[MAXN] , Min[MAXN] , val[MAXC];
 
int main() {
	read(n),read(C);
	for (int i = 1; i <= n; ++i) read(c[i]),read(d[i]),read(h[i]),val[c[i]] = max(val[c[i]] , d[i] * h[i]);
	
	for (int i = 1; i <= C; ++i) {
		val[i] = max(val[i - 1] , val[i]);
		for (int j = i + i; j <= C; j += i) {
			val[j] = max(val[j] , val[i] * (j / i));
		}
	}
	
	int m;
	read(m);
	for (int i = 1; i <= m; ++i) {
		LL D , H;
		read(D),read(H);
		LL ans = upper_bound(val + 1 , val + 1 + C , D * H) - val;
		if(ans != C + 1) write(ans , ' ');
		else puts("-1");
	}
	return 0;
}

CF1567E Star MST

可以说是很套路了。要求以 1 为跟的菊花图是最小生成树。

则每个点到 1 的边都得是他连出去的边中最小的。那么从小到大考虑边权,记录 1 连了多少条边,连上过后就可以与其它连上的边连更大的边咯。

int main() {
	read(n),read(k);
	C[0][0] = 1;
	for (int i = 1; i <= n; ++i) {
		C[i][0] = 1;
		for (int j = 1; j <= i; ++j) C[i][j] = Add(C[i - 1][j - 1] , C[i - 1][j]);
	}
	
	dp[0][1] = 1;
	for (int i = 1; i <= k; ++i) {
		for (int j = 1; j <= n; ++j) {
			for (int w = j; w >= 1; --w) {
				dp[i][j] = Add(dp[i][j] , Mul(C[n - w][j - w] , Mul(qpow(k - i + 1 , (j - w) * (w - 1) + (j - w) * (j - w - 1) / 2) , dp[i - 1][w])));
			}
		}
	}
	
	write(dp[k][n]);
	return 0;
}

CF1657F Words on Tree

一个比较好写的限制方式,用点去限制路径的方向,为路径和每个点分别建两个点。

建边很容易,如当前点的当前值不等于当前路径的顺着,则该路径必为逆序。

跑 2-sat 就完了。

#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <bitset>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define pii pair <int , int>
#define pll pair <LL , LL>
#define mp make_pair
#define fs first
#define sc second
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;

//const int Mxdt=100000; 
//static char buf[Mxdt],*p1=buf,*p2=buf;
//#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,Mxdt,stdin),p1==p2)?EOF:*p1++;

template <typename T>
void read(T &x) {
	T f=1;x=0;char s=getchar();
	while(s<'0'||s>'9') {if(s=='-') f=-1;s=getchar();}
	while(s>='0'&&s<='9') {x=(x<<3)+(x<<1)+(s-'0');s=getchar();}
	x *= f;
}

template <typename T>
void write(T x , char s='\n') {
	if(!x) {putchar('0');putchar(s);return;}
	if(x<0) {putchar('-');x=-x;}
	T tmp[25]={},t=0;
	while(x) tmp[t++]=x%10,x/=10;
	while(t-->0) putchar(tmp[t]+'0');
	putchar(s); 
}

const int MAXN = 4e5 + 5;

int head[MAXN] , to[MAXN << 1] , nxt[MAXN << 1] , cnt;
void add(int u , int v) {nxt[++cnt] = head[u];head[u] = cnt;to[cnt] = v;}

int f[MAXN] , dep[MAXN];
void dfs(int x , int fa) {
	f[x] = fa;dep[x] = dep[fa] + 1;
	for (int i = head[x]; i; i = nxt[i]) {
		int v = to[i];
		if(v == fa) continue;
		dfs(v , x);
	}
}

int num , n , m , v[MAXN] , vis[MAXN];
vector <int> G[MAXN * 4];
char s[MAXN] , a[MAXN] , b[MAXN];

int dfn[MAXN * 4] , low[MAXN * 4] , col[MAXN * 4] , dnum , c , st[MAXN * 4] , top;
void Tarjan(int x) {
	dfn[x] = low[x] = ++dnum;
	st[++top] = x;
	for (auto v:G[x]) {
		if(!dfn[v]) {
			Tarjan(v);
			low[x] = min(low[x] , low[v]);
		}
		else if(!col[v]) low[x] = min(low[x] , dfn[v]);
	}
	if(dfn[x] == low[x]) {
		col[x] = ++c;
		while(st[top] != x) {
			col[st[top]] = c;
			top --;
		}
		top --;
	}
}

int main() {
	read(n),read(m);
	num = n * 2 + m * 2;
	for (int i = 1; i < n; ++i) {
		int u , v;
		read(u),read(v);
		add(u , v) , add(v , u);
	}
	dfs(1 , 0);
	for (int i = 1; i <= m; ++i) {
		int x , y;read(x),read(y);
		scanf("%s" , s + 1);int len = strlen(s + 1);
		int l = 1 , r = len , q = i + n * 2 , nq = i + m + n * 2;
		v[1] = x , v[r] = y;
		while(l < r) {
			if(dep[x] > dep[y]) x = f[x] , v[++l] = x;
			else y = f[y] , v[--r] = y;
		}
		for (int j = 1; j <= len; ++j) {
			int u = v[j];
			if(!vis[u]) vis[u] = 1 , a[u] = s[j] , b[u] = s[len - j + 1];
			if(a[u] != s[j]) G[u].push_back(nq) , G[q].push_back(u + n);
			if(a[u] != s[len - j + 1]) G[u].push_back(q) , G[nq].push_back(u + n);
			if(b[u] != s[j]) G[u + n].push_back(nq) , G[q].push_back(u);
			if(b[u] != s[len - j + 1]) G[u + n].push_back(q) , G[nq].push_back(u);
		}
	}
	
	for (int i = 1; i <= num; ++i) if(!dfn[i]) Tarjan(i);
	
	for (int i = 1; i <= n; ++i) if(col[i] == col[i + n]) return puts("NO"),0;
	for (int i = n * 2 + 1; i <= n * 2 + m; ++i) if(col[i] == col[i + m]) return puts("NO"),0;
	
	puts("YES");
	for (int i = 1; i <= n; ++i) {
		if(!vis[i]) putchar('a');
		else putchar(col[i] < col[i + n]?a[i]:b[i]);
	}
	
	return 0;
}
posted @ 2022-04-08 22:48  Reanap  阅读(32)  评论(0编辑  收藏  举报