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;
}