C - K-th Substring

题解

找出第K大的子串,重复的不计入

这个数据范围可能有什么暴力可以艹过去吧,但是K放大的话这就是后缀自动机板子题啊= =

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
//#define ivorysi
#define MAXN 5005
#define eps 1e-8
using namespace std;
typedef long long int64;
typedef double db;
struct node {
int len,cnt,f;
node *par,*nxt[26];
}pool[MAXN * 3],*tail = pool,*root,*last;
void Build_Sam(int len,int c) {
node *nowp = tail++,*p;
nowp->len = len;
for(p = last ; p && !p->nxt[c] ; p = p->par) {
p->nxt[c] = nowp;
}
if(!p) nowp->par = root;
else {
node *q = p->nxt[c];
if(q->len == p->len + 1) nowp->par = q;
else {
node *cp = tail++;
*cp = *q;cp->cnt = 0;cp->len = p->len + 1;
q->par = nowp->par = cp;
for( ; p && p->nxt[c] == q ; p = p->par) p->nxt[c] = cp;
}
}
last = nowp;
}
int c[MAXN];
node *que[MAXN * 3];
char s[MAXN];
int N,K,M;
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
root = last = tail++;
scanf("%s%d",s + 1,&K);
N = strlen(s + 1);
for(int i = 1 ; i <= N ; ++i) {
Build_Sam(i,s[i] - 'a');
}
M = tail - pool;
for(int i = 0 ; i < M ; ++i) {
c[pool[i].len]++;
}
for(int i = 1 ; i <= N ; ++i) c[i] += c[i - 1];
for(int i = 0 ; i < M ; ++i) {
que[c[pool[i].len]--] = &pool[i];
}
for(int i = 1 ; i <= M ; ++i) que[i]->f = 1;
for(int i = M ; i >= 1 ; --i) {
for(int j = 0 ; j < 26 ; ++j) {
if(que[i]->nxt[j])
que[i]->f += que[i]->nxt[j]->f;
}
}
node *p = root;
while(K > 0) {
for(int i = 0 ; i < 26 ; ++i) {
if(!p->nxt[i]) continue;
if(K <= p->nxt[i]->f) {
putchar('a' + i);
p = p->nxt[i];
--K;
break;
}
else K -= p->nxt[i]->f;
}
}
putchar('\n');
}

D - Equals

题解

给出可交换的两个位置,和一个排列,求最后能达成pi = i的位置

直接用并查集维护连通性,判一下这个位置上的数和该到的位置和初始位置在不在一个联通块

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
//#define ivorysi
#define MAXN 100005
#define eps 1e-8
#define pb push_back
using namespace std;
typedef long long int64;
typedef double db;
int N,M;
int P[MAXN],fa[MAXN];
int getfa(int x) {
return fa[x] == x ? x : fa[x] = getfa(fa[x]);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
scanf("%d%d",&N,&M);
for(int i = 1 ; i <= N ; ++i) scanf("%d",&P[i]);
for(int i = 1 ; i <= N ; ++i) fa[i] = i;
int x,y;
for(int i = 1 ; i <= M ; ++i) {
scanf("%d%d",&x,&y);
fa[getfa(x)] = getfa(y);
}
int cnt = 0;
for(int i = 1 ; i <= N ; ++i) {
if(getfa(P[i]) == getfa(i)) ++cnt;
}
printf("%d\n",cnt);
}

E - Sorted and Sorted

题解

给出一个黑棋N个白棋N个的排列,每一种颜色的球分别标上1 - N,每次可以交换相邻两个球,求白棋相对顺序正确并且黑棋相对顺序正确,所需要最少的步数

动态规划,dp[i][j]表示前边放了i个白棋和j个黑棋所需要的最少步数

dp[i][j] = min(dp[i - 1][j] + cost_w[i - 1][j] , dp[i][j - 1] + cost_b[i][j - 1])

cost_w[i][j]表示前面已经有i个白棋和j个黑棋,在序列末再填一个白棋所需要的步数,cost_b同理

这个可以用树状数组预处理出来

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <ctime>
//#define ivorysi
#define MAXN 2005
#define eps 1e-7
using namespace std;
typedef long long int64;
typedef unsigned int u32;
typedef double db;
int N,a[MAXN * 2];
char c[MAXN * 2][5];
int tr[2][MAXN],cost[2][MAXN][MAXN],dp[MAXN][MAXN];
int lowbit(int x) {return x & (-x);}
void Insert(int id,int x) {
while(x <= N) {
tr[id][x]++;
x += lowbit(x);
}
}
int Query(int id,int x) {
int res = 0;
while(x > 0) {
res += tr[id][x];
x -= lowbit(x);
}
return res;
}
void Solve() {
scanf("%d",&N);
for(int i = 1 ; i <= 2 * N ; ++i) {
scanf("%s%d",c[i] + 1,&a[i]);
}
for(int i = 1 ; i <= 2 * N ; ++i) {
if(c[i][1] == 'W') {
for(int j = 0 ; j <= N ; ++j) {
cost[0][a[i] - 1][j] = (i - 1) - Query(0,a[i] - 1) - Query(1,j);
}
Insert(0,a[i]);
}
else {
for(int j = 0 ; j <= N ; ++j) {
cost[1][j][a[i] - 1] = (i - 1) - Query(0,j) - Query(1,a[i] - 1);
}
Insert(1,a[i]);
}
}
for(int i = 0 ; i <= N ; ++i) {
for(int j = 0 ; j <= N ; ++j) {
if(i == 0 && j == 0) continue;
dp[i][j] = 0x7fffffff;
if(i != 0) {
dp[i][j] = min(dp[i][j],dp[i - 1][j] + cost[0][i - 1][j]);
}
if(j != 0) {
dp[i][j] = min(dp[i][j],dp[i][j - 1] + cost[1][i][j - 1]);
}
}
}
printf("%d\n",dp[N][N]);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}

F - Monochrome Cat

题解

有一只猫,还有一个树(多么现实的故事),树上黑白两种颜色,猫可以选择一个点开始走,每秒可以选择两种事件中的一种

1.翻转当前点颜色

2.到一个相邻点,并必须翻转这个点的颜色

树dp,分三个路径,G[u]表示从点出发到这个点的子树并且不回来,F[u]表示从这个点出发并且回到这个点,H[u]表示一条路径经过这个点并且起点和终点都在它的子树中

转移比较繁琐但是很显然,具体看代码

代码

#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
#include <map>
#include <algorithm>
#include <cmath>
#define MAXN 100005
#define eps 1e-8
//#define ivorysi
#define pii pair<int,int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long int64;
typedef double db;
int N;
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE,sizW[MAXN];
int F[MAXN],G[MAXN],H[MAXN],ans,son[MAXN],fa[MAXN],Ah[MAXN];
char c[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
void addtwo(int u,int v) {
add(u,v);add(v,u);
}
void dfs(int u) {
if(c[u] == 'W') sizW[u] = 1;
else sizW[u] = 0;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa[u]) {
fa[v] = u;
dfs(v);
sizW[u] += sizW[v];
}
}
}
void dfs1(int u,int fa) {
int Sum = 0;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa && sizW[v]) {
dfs1(v,u);
++son[u];
F[u] += F[v];
Sum += F[v];
}
}
if(!son[u] && c[u] == 'W') {
G[u] = F[u] = 1;return;
}
F[u] += son[u] + 1;
if(c[u] == 'W') F[u] += ((son[u] + 1) ^ 1) & 1;
else F[u] += (son[u] + 1 & 1);
G[u] = Sum;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa && sizW[v]) {
G[u] = min(G[u],Sum - F[v] + G[v]);
}
}
G[u] += son[u];
if(c[u] == 'W') G[u] += (son[u] ^ 1) & 1;
else G[u] += son[u] & 1;
G[u] = min(G[u],F[u]);
H[u] = 0x7fffffff;
if(son[u] != 1) { pii t = mp(0,0);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa && sizW[v]) {
if(F[v] - G[v] > t.se) t.se = F[v] - G[v];
if(t.se > t.fi) swap(t.se,t.fi);
}
}
int tmp = c[u] == 'W' ? ((son[u] - 1) ^ 1) & 1 : (son[u] - 1) & 1;
H[u] = Sum - t.fi - t.se + tmp + son[u] - 1;
Ah[u] = tmp;
}
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa && sizW[v]) {
int tmp = Sum - F[v] + H[v] + 1 - Ah[v] + (Ah[v] ^ 1) + son[u];
int t = c[u] == 'W' ? (son[u] ^ 1) & 1 : son[u] & 1;
if(tmp + t < H[u]) {
H[u] = tmp + t;Ah[u] = t;
}
}
}
}
void Init() {
scanf("%d",&N);
int u,v;
for(int i = 1 ; i < N ; ++i) {
scanf("%d%d",&u,&v);
addtwo(u,v);
}
scanf("%s",c + 1);
dfs(1);
}
void Solve() {
ans = 0x7fffffff;
dfs1(1,0);
if(sizW[1] == 0) ans = 0;
else if(sizW[1] == 1) ans = 1;
else {
for(int i = 1 ; i <= N ; ++i) {
if(sizW[i] == sizW[1]) {
ans = min(ans,G[i]);
ans = min(ans,F[i]);
ans = min(ans,H[i]);
}
}
}
printf("%d\n",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
return 0;
}

【AtCoder】ARC097 (C - F)题解的更多相关文章

  1. AtCoder Beginner Contest 238 A - F 题解

    AtCoder Beginner Contest 238 \(A - F\) 题解 A - Exponential or Quadratic 题意 判断 \(2^n > n^2\)是否成立? S ...

  2. AtCoder ExaWizards 2019 简要题解

    AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...

  3. AtCoder Beginner Contest 154 题解

    人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We ...

  4. AtCoder Beginner Contest 153 题解

    目录 AtCoder Beginner Contest 153 题解 A - Serval vs Monster 题意 做法 程序 B - Common Raccoon vs Monster 题意 做 ...

  5. AtCoder Beginner Contest 177 题解

    AtCoder Beginner Contest 177 题解 目录 AtCoder Beginner Contest 177 题解 A - Don't be late B - Substring C ...

  6. AtCoder Beginner Contest 184 题解

    AtCoder Beginner Contest 184 题解 目录 AtCoder Beginner Contest 184 题解 A - Determinant B - Quizzes C - S ...

  7. AtCoder Beginner Contest 173 题解

    AtCoder Beginner Contest 173 题解 目录 AtCoder Beginner Contest 173 题解 A - Payment B - Judge Status Summ ...

  8. AtCoder Beginner Contest 172 题解

    AtCoder Beginner Contest 172 题解 目录 AtCoder Beginner Contest 172 题解 A - Calc B - Minor Change C - Tsu ...

  9. AtCoder Beginner Contest 169 题解

    AtCoder Beginner Contest 169 题解 这场比赛比较简单,证明我没有咕咕咕的时候到了! A - Multiplication 1 没什么好说的,直接读入两个数输出乘积就好了. ...

  10. AtCoder Beginner Contest 148 题解

    目录 AtCoder Beginner Contest 148 题解 前言 A - Round One 题意 做法 程序 B - Strings with the Same Length 题意 做法 ...

随机推荐

  1. Hadoop生态圈-hbase介绍-伪分布式安装

    Hadoop生态圈-hbase介绍-伪分布式安装 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.HBase简介 HBase是一个分布式的,持久的,强一致性的存储系统,具有近似最 ...

  2. Challenge 18

    Challenge 18给你一个长度为 n 的非负整数序列 a 和 m 个询问 l, r, p, k,表示询问在 a[l .. r] 中 a[i]%p=k 的 i 的个数. 思路: 将序列分为根号n块 ...

  3. MapReduce (hive表SequenceFile的结果做输入)、MultipleOutputs和Reduce端迭代iterable的一些说明

    很长时间以来一直写hive,嵌套脚本.偶尔写UDF.  最近用Hive的dynamic partition和多路插入做一些事情,很遗憾的结果是非常不稳定,有时能成功,有时失败.(可能是因为hive版本 ...

  4. Sparse AutoEncoder简介

    1. AutoEncoder AutoEncoder是一种特殊的三层神经网络, 其输出等于输入:\(y^{(i)}=x^{(i)}\), 如下图所示: 亦即AutoEncoder想学到的函数为\(f_ ...

  5. 学号20155308 2016-2017-2 《Java程序设计》第6周学习总结

    学号20155308 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入与输出 目的:文件的读写:网络上传数据的基础:同样要掌握父类中方法. 10. ...

  6. Css3帧动画深入探寻,讲点项目中实际会碰到的问题

    先加个副标题XD --如何解决background-size为100%下处理@keyframes 正是在项目中遇到副标题,才引起我更深入的探寻 先略带一下基本的css3动画 css3的动画实现是通过属 ...

  7. Oracle03--子查询

    1. 子查询 子查询也称之为嵌套子句查询. 1.1. 语法 语法上的运行使用规则: l 子查询 (内查询.嵌套子句) 在主查询之前一次执行完成.(子查询先执行) l 子查询的结果被主查询使用 (外查询 ...

  8. 差分约束系统 + spfa(A - Layout POJ - 3169)

    题目链接:https://cn.vjudge.net/contest/276233#problem/A 差分约束系统,假设当前有三个不等式 x- y <=t1 y-z<=t2 x-z< ...

  9. 说说C语言运算符的“优先级”与“结合性”

    论坛和博客上常常看到关于C语言中运算符的迷惑,甚至是错误的解读.这样的迷惑或解读大都发生在表达式中存在着较为复杂的副作用时.但从本质上看,仍然是概念理解上的偏差.本文试图通过对三个典型表达式的分析,集 ...

  10. 新电脑重新安装win10+python3.6+anaconda+tensorflow1.12(gpu版)

    安装了一天的软件,遇到了很多坑,在快泪崩的时候,始终以磨刀不误砍柴工鼓励自己,坚持安好了,话不多说,上干货: 前言:        TensorFlow 有两个版本:CPU 版本和 GPU 版本.GP ...