【AtCoder】AGC029(A-E)
A - Irreversible operation
题解
把每个B后面的W个数累加起来即可
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 1000005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
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);
}
char s[200005];
int64 ans = 0;
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
scanf("%s",s + 1);
int64 t = 0;
int N = strlen(s + 1);
for(int i = N ; i >= 1 ; --i) {
if(s[i] == 'W') ++t;
else ans += t;
}
out(ans);enter;
}
B - Powers of two
题解
这比赛打的太难受了
这个我花了一个树结构,蒙了一个dp,然后wa了,去硬上T2
最后发现我把一个N改成离散化后的tot就A了
就是考虑一个点,和它组成恰好大于它的\(2^{i}\)的值只有一个,构成了一片森林,对于每个森林从底向上更新,如果父亲和儿子能配对就尽可能多的配对
每个\(2^{i}\)的点若有剩余再两两配对
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
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 * 10];
map<int,int> mm;
int val[MAXN],A[MAXN],N,tot,ans;
int head[MAXN],sumE,dp[MAXN];
bool vis[MAXN];
int lowbit(int x) {
return x & (-x);
}
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
void Init() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
read(A[i]);
val[i] = A[i];
mm[A[i]]++;
}
sort(val + 1,val + N + 1);
tot = unique(val + 1,val + N + 1) - val - 1;
for(int i = 1 ; i <= N ; ++i) {
int a = val[i];
int k = lower_bound(val + 1,val + tot + 1,a) - val;
for(int64 t = 1 ; t <= 1073741824 ; t <<= 1) {
if(t > 2 * a) {
if(mm[t - a] == 0) continue;
int h = lower_bound(val + 1,val + tot + 1,t - a) - val;
add(k,h);
}
}
}
}
void dfs(int u) {
vis[u] = 1;
dp[u] = mm[val[u]];
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(!vis[v]) {
dfs(v);
int t = min(dp[u],dp[v]);
dp[u] -= t;
dp[v] -= t;
ans += t;
}
}
}
void Solve() {
for(int i = 1 ; i <= tot ; ++i) {
if(!vis[i]) dfs(i);
if(lowbit(val[i]) == val[i]) ans += dp[i] / 2;
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
C - Lexicographic constraints
题解
好不容易想到了一个分段维护一个字符个数进制下的数
没想到二分,gg了
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
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];
int pw[MAXN][25],cnt[MAXN],ans;
vector<pii > v;
void Init() {
read(N);
for(int i = 1 ; i <= N ; ++i) read(A[i]);
cnt[1] = 1000000000;
for(int i = 1 ; i <= N ; ++i) {
pw[i][0] = 1;
for(int j = 1 ; j <= 20 ; ++j) {
if(pw[i][j - 1] > N / i) {
cnt[i] = j - 1;break;
}
pw[i][j] = pw[i][j - 1] * i;
}
}
}
bool check(int mid) {
v.clear();
v.pb(mp(A[1],0));int sum = A[1];
for(int i = 2 ; i <= N ; ++i) {
if(A[i] <= A[i - 1]) {
if(mid == 1) return false;
if(sum < A[i - 1]) {v.pb(mp(A[i - 1] - sum,0));sum = A[i - 1];}
int s = v.size() - 1;
for(int k = s ; k >= 0 ; --k) {
if(sum - v[k].fi >= A[i]) {sum -= v[k].fi;v.pop_back();}
else {
int t = sum - A[i];
if(t > cnt[mid]) v[k].se = 0;
else v[k].se /= pw[mid][t];
v[k].fi -= t;
sum = A[i];
}
if(sum == A[i]) break;
}
s = v.size() - 1;
for(int k = s ; k >= 0 ; --k) {
if(v[k].fi <= cnt[mid]) {
if(v[k].se + 1 < pw[mid][v[k].fi]) {++v[k].se;break;}
else {
v[k].se = 0;if(k == 0) return false;
}
}
else {++v[k].se;break;}
}
}
}
return true;
}
void Solve() {
int l = 1,r = N;
while(l < r) {
int mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
out(l);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
D - Grid game
题解
这题好水啊= =开D我就win了啊,sdC一直不过太难受了啊
就是考虑我们肯定是走到某个障碍物上面,游戏结束了
如何判断能不能走到呢,首先如果这一列是\(j\),我们所在的行\(i\)必须大于等于\(j\),如果有一个连成一串的障碍物从\((j,j)\)开始往下压
每次最多压了多少,就是当前列最靠下不能走的点\(h\),求一个\(t = h - i + 1\)
\(t\)每次取一个前缀\(max\),然后对于每一列把行大于等于\(j + t\)的障碍物都设成不合法即可
把每一列能走到最靠上的障碍物取一个\(min\)
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
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 H,W,N;
vector<int> v[MAXN];
bool pass[MAXN];
void Solve() {
read(H);read(W);read(N);
int x,y;
for(int i = 1 ; i <= N ; ++i) {
read(x);read(y);
v[y].pb(x);
}
for(int i = 1 ; i <= W ; ++i) v[i].pb(H + 1);
sort(v[1].begin(),v[1].end());
int ans = v[1][0] - 1;
int t = 0;
for(int i = 2 ; i <= W ; ++i) {
sort(v[i].begin(),v[i].end());
int s = v[i].size();
int m = 0;
for(int k = 0 ; k < s ; ++k) {
if(v[i][k] <= i + t) {pass[v[i][k]] = 1;m = max(v[i][k],m);}
else if(pass[v[i][k] - 1]) {pass[v[i][k]] = 1;m = max(v[i][k],m);}
else {
ans = min(ans,v[i][k] - 1);
break;
}
}
t = max(t,m - i + 1);
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
E - Wandering TKHS
题解
关注一下一个路径的根缀最大值
把根缀最大值相同的部分挑出来
我们发现一个根缀最大值是\(u\),\(u\)的某个儿子是\(v\),\(v\)中的所有节点要走到\(u\),就要经过\(v\)中所有根缀最大值为\(u\)的部分,这个可以差分实现
而根缀最大值自身讨论起来有点麻烦,直接搜索即可
代码
#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
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;
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE;
int mv[MAXN],siz[MAXN],d[MAXN],c[MAXN],son[MAXN];
void add(int u,int v) {
E[++sumE].next = head[u];
E[sumE].to = v;
head[u] = sumE;
}
void calc(int u,int fa,int val) {
son[u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa && v < val) {
calc(v,u,val);
son[u] += son[v];
}
}
}
void dfs(int u,int fa) {
mv[u] = max(mv[fa],u);
siz[u] = 1;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs(v,u);
siz[u] += siz[v];
d[u] += d[v];
}
}
if(mv[u] == u) {
calc(u,fa,mv[fa]);
d[u] = -siz[u];
}
if(mv[fa] == fa) d[u] += siz[u];
}
void dfs2(int u,int fa) {
if(fa) {
if(mv[u] == u) {c[u] += son[u];}
else if(mv[fa] == fa) {c[u] -= son[u];c[u] += d[u];}
c[u] += c[fa];
}
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs2(v,u);
}
}
}
void Init() {
read(N);
int x,y;
for(int i = 1 ; i < N ; ++i) {
read(x);read(y);add(x,y);add(y,x);
}
}
void Solve() {
dfs(1,0);
dfs2(1,0);
for(int i = 2 ; i <= N ; ++i) {
out(c[i]);
i == N ? enter : space;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}
F - Construction of a tree
\(2 \cdot 10^{5}\)的网络流,有毒,不会卡常,弃疗了,再见
【AtCoder】AGC029(A-E)的更多相关文章
- 【AtCoder】ARC097 (C - F)题解
C - K-th Substring 题解 找出第K大的子串,重复的不计入 这个数据范围可能有什么暴力可以艹过去吧,但是K放大的话这就是后缀自动机板子题啊= = 代码 #include <ios ...
- 【BZOJ2599】Race(点分治)
[BZOJ2599]Race(点分治) 题面 BZOJ权限题,洛谷 题解 好久没写过点分治了... 在ppl的帮助下终于想起来了 orz ppl 首先回忆一下怎么求有没有正好是\(K\)的路径 维护一 ...
- 【HDU4622】Reincarnation(后缀自动机)
[HDU4622]Reincarnation(后缀自动机) 题面 Vjudge 题意:给定一个串,每次询问l~r组成的子串的不同子串个数 题解 看到字符串的大小很小 而询问数太多 所以我们预处理任意的 ...
- 【BZOJ2882】工艺(后缀自动机)
[BZOJ2882]工艺(后缀自动机) 题面 BZOJ权限题,良心洛谷 题解 还是一样的,先把串在后面接一遍 然后构建\(SAM\) 直接按照字典序输出\(n\)次就行了 #include<io ...
- 【BZOJ2882】工艺(后缀数组)
[BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #i ...
- 【BZOJ3277】串(后缀自动机)
[BZOJ3277]串(后缀自动机) 题面 BZOJ 题解 广义后缀自动机??? 照着别人的打了一遍.. 相当于每个串都构建一个后缀自动机 构建完一个串之后,直接把当前的last指回root就行了?? ...
- 【BZOJ3238】差异(后缀自动机)
[BZOJ3238]差异(后缀自动机) 题面 BZOJ 题解 前面的东西直接暴力算就行了 其实没必要算的正正好 为了方便的后面的计算 我们不考虑\(i,j\)的顺序问题 也就是先求出\(\sum_{i ...
- 【BZOJ3998】弦论(后缀自动机)
[BZOJ3998]弦论(后缀自动机) 题面 BZOJ 题解 这题应该很简单 构建出\(SAM\)后 求出每个点往后还能构建出几个串 按照拓扑序\(dp\)一些就好了 然后就是第\(k\)大,随便搞一 ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
随机推荐
- bzoj2152 (点分治)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2152 思路: 要想两点之间距离为3的倍数,那么用t0表示该点距离重心的距离对3取模为0, ...
- 【BZOJ3872】Ant colony(二分,动态规划)
[BZOJ3872]Ant colony(二分,动态规划) 题面 又是权限题... Description There is an entrance to the ant hill in every ...
- 【bzoj3196】 Tyvj1730—二逼平衡树
http://www.lydsy.com/JudgeOnline/problem.php?id=3196 (题目链接) 题意 1.查询k在区间内的排名:2.查询区间内排名为k的值:3.修改某一位值上的 ...
- PostgreSQL——前言
PostgreSQL是以加州大学伯克利分校计算机系开发的POSTGRES, 版本 4.2为基础的对象关系型数据库管理系统(ORDBMS).POSTGRES 领先的许多概念在很久以后才出现在一些商业数据 ...
- 【CF706D】Vasiliy's Multiset Trie+贪心
题目大意:需要维护一种数据结构,支持以下三种操作:插入一个数,删除一个数,查询该数据结构中的数异或给定数的最大值. 题解:如果没有删除操作就是一个标准的 Trie 上贪心求最大异或和问题.现在需要支持 ...
- RPC与RMI的区别
分布式项目按照以下发展经历了以下技术: CORBA: RMI:基于远程接口的调用 RMI-RROP:这是RMI与CORBA的结合,用在了EJB技术上,EJB留给世界上是优秀的理论和糟糕的架构. WEB ...
- P2513 [HAOI2009]逆序对数列
P2513 [HAOI2009]逆序对数列 题目描述 对于一个数列{ai},如果有iaj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数.那 ...
- Java入门系列(九)Java API
String,StringBuilder,StringBuffer三者的区别 1.首先说运行速度,或者说是执行速度 在这方面运行速度快慢为:StringBuilder > StringBuffe ...
- js 正则之 检测素数
相信很多人应该看过这篇文章,我第一次看到的时候是11年的样子,那时候学vbs的时候看过这个问题.原文<检查素数的正则表达式>,在文章里已经解释了他是怎么判断的,我就不啰嗦了.我们来说说 j ...
- php拾遗: 类型约束
突然间什么都不想干,感觉就像来大姨夫一样..但是又不能断了每个工作日都写博客的习惯..所以今天水一下吧. PHP用了快2年了,但是这东西竟然第一次看到,突然间,觉得自己有掉回战五渣的行列了.翻开官方文 ...