【AtCoder】ARC101题解
C - Candles
题解
点燃的一定是连续的一段,枚举左端点即可
代码
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define MAXN 1000005
#define mo 999999137
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
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,K;
int64 a[100005];
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);read(K);
for(int i = 1 ; i <= N ; ++i) {
read(a[i]);
}
int64 ans = 1e16;
for(int i = 1 ; i <= N - K + 1; ++i) {
int t = i + K - 1;
if(1LL * a[i] * a[t] > 0) {
ans = min(ans,max(abs(a[i]),abs(a[t])));
}
else ans = min(ans,min(-2 * a[i] + a[t],2 * a[t] - a[i]));
}
out(ans);enter;
return 0;
}
D - Median of Medians
二分一个值作为中位数的中位数,把大于这个数的设成1,小于等于这个数的设成0
然后我们就需要知道小于等于这个数做中位数的区间有多少个,用树状数组维护,和全部区间个数的一半比较一下即可
题解
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define MAXN 1000005
#define mo 999999137
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
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;
int64 M;
int a[100005],num[100005],cnt;
int sum[100005][2],c[200005];
int tr[200005];
int lowbit(int x) {return x & -x;}
void Insert(int x,int v) {
while(x <= 2 * N + 1) {
tr[x] += v;
x += lowbit(x);
}
}
int Query(int x) {
int res = 0;
while(x > 0) {
res += tr[x];
x -= lowbit(x);
}
return res;
}
bool check(int x) {
for(int i = 1 ; i <= N ; ++i) {
sum[i][0] = sum[i - 1][0] + (a[i] <= x);
sum[i][1] = sum[i - 1][1] + (a[i] > x);
}
memset(tr,0,sizeof(tr));
for(int i = 1 ; i <= N ; ++i) Insert(sum[i][1] - sum[i][0] + N + 1,1);
int64 res = 0;
for(int i = 1 ; i <= N ; ++i) {
int t = sum[i - 1][1] - sum[i - 1][0] + N + 1;
res += Query(t - 1);
Insert(sum[i][1] - sum[i][0] + N + 1,-1);
}
return res >= M;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(N);
for(int i = 1 ; i <= N ; ++i) {read(a[i]);num[i] = a[i];}
M = 1LL * N * (N + 1) / 2;
M = M / 2 + 1;
sort(num + 1,num + N + 1);
cnt = unique(num + 1,num + N + 1) - num - 1;
int L = 1,R = cnt;
while(L < R) {
int mid = (L + R) >> 1;
if(check(num[mid])) R = mid;
else L = mid + 1;
}
out(num[L]);enter;
return 0;
}
E - Ribbons on Tree
题解
我们用容斥来考虑,设\(g(i)\)为至少有i条边没有被覆盖的方案数,那么答案就是
\(\sum_{i = 1}^{n} (-1)^{i}g(i)\)考虑一边dp一边求g的系数
用dp[u][i][0/1]表示以u为根的子树里,i个点匹配了,系数为-1或1的方案数
转移的话用类似树背包的转移
如果不是根的话枚举父边是不是没有被覆盖
#include <bits/stdc++.h>
#define enter putchar('\n')
#define space putchar(' ')
#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define MAXN 5005
#define mo 99994711
#define pb push_back
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;T f = 1;char c = getchar();
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);
}
const int MOD = 1000000007;
int N;
struct node {
int to,next;
}E[MAXN * 2];
int head[MAXN],sumE;
int dp[MAXN][MAXN][2],fac[MAXN],inv[MAXN],invfac[MAXN],p[MAXN],siz[MAXN],tmp[MAXN][2];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
void update(int &x,int y) {
x = inc(x,y);
}
int C(int n,int m) {
if(n < m) return 0;
return mul(fac[n],mul(invfac[m],invfac[n - m]));
}
void dfs(int u,int fa) {
dp[u][0][0] = 1;
siz[u] = 0;
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs(v,u);
for(int i = 0 ; i <= siz[u] + siz[v] ; ++i) tmp[i][0] = tmp[i][1] = 0;
for(int i = 0 ; i <= siz[u] ; ++i) {
for(int j = 0 ; j <= siz[v] ; ++j) {
for(int k = 0 ; k <= 1 ; ++k) {
for(int h = 0 ; h <= 1 ; ++h) {
update(tmp[i + j][k ^ h],mul(dp[u][i][k],dp[v][j][h]));
}
}
}
}
for(int i = 0 ; i <= siz[u] + siz[v] ; ++i) {
dp[u][i][0] = tmp[i][0];
dp[u][i][1] = tmp[i][1];
}
siz[u] += siz[v];
}
}
++siz[u];
if(fa) {
for(int i = siz[u] - 1; i >= 0 ; --i) {
for(int k = 0 ; k <= 1 ; ++k) {
update(dp[u][siz[u]][k],mul(dp[u][i][k ^ 1],p[siz[u] - i]));
}
}
}
}
void Solve() {
read(N);
int u,v;
for(int i = 1 ; i < N ; ++i) {
read(u);read(v);add(u,v);add(v,u);
}
inv[1] = 1;
for(int i = 2 ; i <= N ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i);
fac[0] = invfac[0] = 1;
for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i),invfac[i] = mul(invfac[i - 1],inv[i]);
p[0] = 1;
for(int i = 1 ; i <= N ; ++i) {
if(i & 1) p[i] = 0;
else p[i] = mul(p[i - 2],i - 1);
}
dfs(1,0);
int ans = 0;
for(int i = 0 ; i <= N ; ++i) {
ans = inc(ans,mul(dp[1][i][0],p[N - i]));
ans = inc(ans,MOD - mul(dp[1][i][1],p[N - i]));
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}
F - Robots and Exits
题解
把每个机器人到左边最近的距离记作\(a_i\),到右边最近的距离记作\(b_i\)
我们把这个点\((a_i,b_i)\)画在平面直角坐标系里
然后我们记\((x,y)\)为最左的点远离初始点x的距离,到过最右的点远离初始点y的距离
每次可以走到\((x + 1,y)\)或\((x,y + 1)\)
在路径下方的点是从右边出口走的,上方的点是从左边出口走的
我们就是要看走的折线能把点分成几个集合,用树状数组维护来转移即可
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define enter putchar('\n')
#define space putchar(' ')
#define fi first
#define se second
#define mp make_pair
#define MAXN 100005
//#define ivorysi
#define pii pair<int,int>
using namespace std;
typedef long long int64;
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) {putchar('-');x = -x;}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int N,M;
int x[MAXN],y[MAXN],tot,v[MAXN],cnt,tr[MAXN],f[MAXN];
pii poi[MAXN];
int lowbit(int x) {
return x & -x;
}
int inc(int a,int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
void Insert(int x,int v) {
while(x <= cnt) {
tr[x] = inc(tr[x],v);
x += lowbit(x);
}
}
int Query(int x) {
int res = 0;
while(x > 0) {
res = inc(res,tr[x]);
x -= lowbit(x);
}
return res;
}
void Solve() {
read(N);read(M);
for(int i = 1 ; i <= N ; ++i) read(x[i]);
for(int i = 1 ; i <= M ; ++i) read(y[i]);
int p = 1;
for(int i = 1 ; i <= N ; ++i) {
while(p + 1 <= M && y[p + 1] < x[i]) ++p;
if(p >= M) break;
if(x[i] > y[p]) poi[++tot] = mp(x[i] - y[p],y[p + 1] - x[i]);
}
sort(poi + 1,poi + tot + 1);
tot = unique(poi + 1,poi + tot + 1) - poi - 1;
for(int i = 1 ; i <= tot ; ++i) {
v[++cnt] = poi[i].se;
}
v[++cnt] = 0;
sort(v + 1,v + cnt + 1);
cnt = unique(v + 1,v + cnt + 1) - v - 1;
Insert(1,1);
int ans = 1;p = 0;
for(int i = 1 ; i <= tot ; ++i) {
while(p + 1 <= tot && poi[p + 1].fi < poi[i].fi) {
++p;
int t = lower_bound(v + 1,v + cnt + 1,poi[p].se) - v;
Insert(t,f[p]);
}
int t = lower_bound(v + 1,v + cnt + 1,poi[i].se) - v;
f[i] = Query(t - 1);
ans = inc(ans,f[i]);
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
}
【AtCoder】ARC101题解的更多相关文章
- AtCoder ExaWizards2019题解
AtCoder ExaWizards2019题解 AtCoder (因为代码直接用模板写的,可能有点冗长) A.Regular Triangle 给你三根棍子的长度,问你能否用他们组成等边三角形. 什 ...
- Atcoder ARC101 E 树dp
https://arc101.contest.atcoder.jp/tasks/arc101_c 题解是也是dp,好像是容斥做的,但是看不懂,而且也好像没讲怎么变n^2,看了写大佬的代码,自己理解了一 ...
- Atcoder ARC101 Ribbons on Tree
题解: 前面牛客网的那个比赛也有一道容斥+dp 两道感觉都挺不错的 比较容易想到的是 f[i][j]表示枚举到了i点,子树中有j个未匹配 这样的话我们需要枚举儿子中匹配状态 这样是n^2的(这是个经典 ...
- KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解
KYOCERA Programming Contest 2021(AtCoder Beginner Contest 200) 题解 哦淦我已经菜到被ABC吊打了. A - Century 首先把当前年 ...
- AT2370 Piling Up
https://www.luogu.org/jump/atcoder/2370 题解 答案不是\(2^{2m}\)因为每轮的第一次取球可能会不够. 我们可以设\(dp[i][j]\)表示到了第\(i\ ...
- Triple Shift
来源:Atcoder ARC 136 B - Triple Shift (atcoder.jp) 题解:这道题我们不可能去硬模拟(大多数这种题都不能这样去模拟的),然后我们就要去发现特性, 发现把 a ...
- 重修 Slope Trick(看这篇绝对够!)
Slope Trick 算法存在十余载了,但是我没有找到多少拍手叫好的讲解 blog,所以凭借本人粗拙的理解来写这篇文章. 本文除标明外所有图片均为本人手绘(若丑见谅),画图真的不容易啊 qwq(无耻 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
- AtCoder ExaWizards 2019 简要题解
AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...
随机推荐
- 「NOI2018」你的名字
「NOI2018」你的名字 题目描述 小A 被选为了\(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了. 由于\(ION\) 已经举办了很多届 ...
- Graham's Scan法求解凸包问题
概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念.用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有点的.严谨的定义和相关概念参 ...
- 51nod1462 树据结构(树链剖分+线段树)
这题好久之前就被学长安利了...一直没写珍藏在收藏夹一个不为人知的角落233 这题怎么做...我们来数形结合,横坐标为$t_i$被加的次数(可看作时间$t$),纵坐标为$v_i$,那么$t_i$实际上 ...
- NOIP2017 列队——动态开点线段树
Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为 ...
- 位运算的一种应用 和 hiho1516过河解题报告
初始i=s 每次:i=(i-1) & s 直到i=0 etc.11000100000100000000 10000=10001 & 1100001000=01111 & 110 ...
- git-jenkins-k8s构建tomcat项目实践
相关环境(部署安装略...):jenkins 安装k8s 集群环境部署docker 私有仓库搭建 jenkins 创建项目 Execute shell 构建docker镜像上传到私有仓库,以构建时间做 ...
- 模拟QQ聊天与视频聊天同时进行-------java基础知识总结
前言:多线程的知识 代码: package com.day13.math; /** * 类说明 :模拟QQ聊天与视频聊天同时进行 * @author 作者 : chenyanlong * @versi ...
- C# 获取文件图标
今天突然想到一个问题,如何去获取一个文件的关联图标呢?于是就上网搜索了一下.现总结如下: 首先明确问题:获取一个文件的关联图标或者是某个类型文件的显示图标. 在网上搜了一圈,发现方法还是比较多的,但是 ...
- CM记录-CDH大数据平台实施经验总结2016(转载)
CDH大数据平台实施经验总结2016(转载) 2016年负责实施了一个生产环境的大数据平台,用的CDH平台+docker容器的方式,过了快半年了,现在把总结发出来. 1. 平台规划注意事项 1.1 业 ...
- History of Monte Carlo Methods - Part 1
History of Monte Carlo Methods - Part 1 Some time ago in June 2013 I gave a lab tutorial on Monte Ca ...