AGC008

A - Simple Calculator

如果符号相同,那么如果y比x大直接走,否则需要两次反号

如果符号不同,需要绝对值的差加一次反号

如果有一个是0,且y比x要小,那只需要一次反号

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 5005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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);
}
int64 x,y;
void Solve() {
read(x);read(y);
if(x * y >= 0) {
if(y >= x) {out(y - x);enter;}
else if(x * y != 0) {out(x - y + 2);enter;}
else {out(x - y + 1);enter;}
}
else {
out(abs(abs(x) - abs(y)) + 1);enter;
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

B - Contiguous Repainting

合法的序列中必须有一段长度大于等于K的同色的段即可

枚举同色段的位置和它的颜色,只需要加上两边所有的正数即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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 pre[MAXN],suf[MAXN],a[MAXN],sum[MAXN];
void Solve() {
read(N);read(K); for(int i = 1 ; i <= N ; ++i) {
read(a[i]);
sum[i] = sum[i - 1] + a[i];
pre[i] = pre[i - 1];
if(a[i] > 0) pre[i] = pre[i] + a[i];
}
for(int i = N ; i >= 1 ; --i) {
suf[i] = suf[i + 1];
if(a[i] > 0) suf[i] = suf[i] + a[i];
}
int64 ans = 0;
for(int i = 1 ; i <= N ; ++i) {
int r = i + K - 1;
if(r > N) break;
int64 all = pre[i - 1] + suf[r + 1];
if(sum[r] - sum[i - 1] > 0) all += sum[r] - sum[i - 1];
ans = max(ans,all);
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

C - Tetromino Tiling

简单分析一下只有I,O,L,J是有用的

我们先尽量一个I,一个L,一个J拼成一个长度为6的

然后剩下的II两两组合,L两两组合,J两两组合

如果I,J,L剩下的有两个,且我拼过一个长度为6的,那么我把这个长度为6的拆开分给这两个

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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);
}
int64 aI,aO,aT,aJ,aL,aS,aZ;
int64 ans = 0;
void Solve() {
read(aI);read(aO);read(aT);read(aJ);read(aL);read(aS);read(aZ);
ans = aO;
int64 t = min(aI,min(aJ,aL));
ans += 3 * t;
aI -= t;aJ -= t;aL -= t;
ans += (aI / 2) * 2;aI %= 2;
ans += (aJ / 2) * 2;aJ %= 2;
ans += (aL / 2) * 2;aL %= 2;
if(aI + aJ + aL >= 2) {
if(t) {
ans -= 3;ans += 4;
}
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

D - K-th K

直接把这些位置排序,然后按照需要给位置最前且没有满足的位置填需要的数

然后如果一个位置过去了,我们把它后面的数,例如第2个2填完了,我们把N - 2个2扔进一个vector,vector里面的数不在乎顺序,随取随用

如果没有数用了也是不合法

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 505
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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;
int x[MAXN],id[MAXN];
int val[MAXN * MAXN];
bool vis[MAXN];
vector<int> r;
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
read(x[i]);
val[x[i]] = i;
id[i] = i;
}
sort(id + 1,id + N + 1,[](int a,int b){return x[a] < x[b];});
int p = 1,rem = id[1] - 1;
vis[1] = 1;
for(int i = 1 ; i <= N * N ; ++i) {
if(val[i]) {
if(!vis[val[i]]) {puts("No");return;}
for(int j = 1 ; j <= N - val[i] ; ++j) r.pb(val[i]);
}
else {
while(!rem && p < N) {++p;rem = id[p] - 1;}
if(rem) {
val[i] = id[p];
--rem;
if(!rem) vis[id[p]] = 1;
}
else {
if(r.size() == 0) {puts("No");return;}
val[i] = r.back();r.pop_back();
}
}
}
puts("Yes");
for(int i = 1 ; i <= N * N ; ++i) {out(val[i]);space;}
enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

E - Next or Nextnext

我们直接建一张i->a[i]的图,最后我们用排列i->p[i]建出的图相当于一次走一步或者一次走两步

发现这是分开的很多基环内向树,我们分开算答案统计即可

如果有一个环,环上的某些点挂着链,链必须只是单链,否则就不合法

相当于往环上放点,如果一个点上挂着链,那么这个点之前链长的边都会被这个点占据

我们把占据的都标记好了,发现这些占据不重合的时候才算合法

这个时候我们看看这个点链长+1前位置的边是否被占据,如果没有被占据,这个点挂着的链在环上就有两种填法

如果只有一个环,没有链

那么奇数的环(1除外)可以有两种走法

而且两个数量相同的环可以拼成一个新环,这个环上每个人到目标位置距离都是2

可以用一个dp来计算相同点数的环的分配方案

把这些方案都乘起来就是总方案

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 100005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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,head[MAXN],sumE;
int a[MAXN];
int deg[MAXN],line[MAXN];
bool vis[MAXN],mark[MAXN];
int cnt[MAXN],dp[MAXN],f[MAXN];
vector<int> v;
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 update(int &x,int y) {
x = inc(x,y);
}
queue<int> Q;
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) {
read(a[i]);
++deg[a[i]];
}
for(int i = 1 ; i <= N ; ++i) {
if(!deg[i]) Q.push(i);
}
while(!Q.empty()) {
int u = Q.front();Q.pop();
vis[u] = 1;
if(line[a[u]]) {puts("0");return;}
line[a[u]] = line[u] + 1;
if(!(--deg[a[u]])) Q.push(a[u]);
}
int ans = 1;
for(int i = 1 ; i <= N ; ++i) {
if(!vis[i]) {
v.clear();
int p = i;v.pb(i);vis[p] = 1;p = a[p];
while(p != i) {
vis[p] = 1;
v.pb(p);
p = a[p]; }
int n = v.size();
bool no = 1;
for(int j = 0 ; j < n ; ++j) {
mark[j] = 0;
if(line[v[j]]) no = 0;
}
if(no) {cnt[n]++;continue;}
for(int j = 0 ; j < n ; ++j) {
for(int k = 0 ; k < line[v[j]] ; ++k) {
int t = ((j - k) % n + n) % n;
if(mark[t]) {puts("0");return;}
mark[t] = 1;
}
}
for(int j = 0 ; j < n ; ++j) {
if(!line[v[j]]) continue;
int t = ((j - line[v[j]]) % n + n) % n;
if(!mark[t]) ans = mul(ans,2);
}
}
}
for(int i = 1 ; i <= N ; ++i) {
if(cnt[i]) {
for(int j = 1 ; j <= cnt[i] ; ++j) dp[j] = 0;
dp[0] = 1;
for(int j = 1 ; j <= cnt[i] ; ++j) {
dp[j] = dp[j - 1];
if((i & 1) && i != 1) update(dp[j],dp[j - 1]);
if(j >= 2) {
update(dp[j],mul(j - 1,mul(i,dp[j - 2])));
}
}
ans = mul(ans,dp[cnt[i]]);
}
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

F - Black Radius

1300分的话,如果\(f(x,d)\)即从x点延伸d长度不为全集,那么如果d可以更小,我们就不统计,也就是附近有个点\(f(y,d - 1)\)和它覆盖的是一样的

这个可以用x当根每个儿子最大深度统计出来,就是两次树dp

把这个最大的d记做\(high[x]\)

然后我们对于每个点记录一个\(low[x]\)表示最小能从哪个点往上延伸

我们在求high的时候会发现每个点和它当根的时候深度最大的那个儿子可能有一个low上的转移关系,我们记录下来

然后我们high从小到大枚举每个点,如果这个点是偏爱点,那么low是0,如果这个点low <= high,就证明这个点大于low的时候已经是偏爱点一样了,可以更新周围的点,利用我们求的转移关系然后更新周围点即可

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define space putchar(' ')
#define enter putchar('\n')
#define eps 1e-10
#define MAXN 200005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef unsigned int u32;
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);
}
struct node {
int to,next;
}E[MAXN * 2];
int N,head[MAXN],sumE,dep[MAXN],fr[MAXN],high[MAXN],low[MAXN];
char s[MAXN];
vector<int> rec[MAXN];
vector<pii > to[MAXN];
void add(int u,int v) {
E[++sumE].to = v;
E[sumE].next = head[u];
head[u] = sumE;
}
void dfs1(int u,int fa) {
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs1(v,u);
dep[u] = max(dep[u],dep[v] + 1);
}
}
}
void dfs2(int u,int fa) {
vector<pii > vec;
dep[u] = max(dep[u],fr[u] + 1);
vec.pb(mp(1,u));
if(fa) vec.pb(mp(fr[u] + 2,fa));
pii p = mp(0,0);
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
vec.pb(mp(dep[v] + 2,v));
if(dep[v] > dep[p.se]) p.se = v;
if(dep[p.se] > dep[p.fi]) swap(p.fi,p.se);
}
}
sort(vec.begin(),vec.end());
high[u] = dep[u] - 1;
int s = vec.size() - 1;
high[u] = min(high[u],vec[s - 1].fi);
if(high[u] < dep[u] - 1){
to[u].pb(mp(vec[s].se,high[u]));
}
vec.clear();
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
fr[v] = max(fr[v],fr[u] + 1);
if(v != p.fi) fr[v] = max(fr[v],dep[p.fi] + 1);
if(v != p.se) fr[v] = max(fr[v],dep[p.se] + 1);
}
}
for(int i = head[u] ; i ; i = E[i].next) {
int v = E[i].to;
if(v != fa) {
dfs2(v,u);
}
}
}
void Solve() {
read(N);
int a,b;
for(int i = 1 ; i < N ; ++i) {
read(a);read(b);add(a,b);add(b,a);
}
scanf("%s",s + 1);
dep[0] = -1;fr[1] = -1;
dfs1(1,0);dfs2(1,0);
for(int i = 1 ; i <= N ; ++i) {
rec[high[i]].pb(i);
low[i] = high[i] + 1;
}
for(int i = 0 ; i <= N ; ++i) {
for(auto v : rec[i]) {
if(s[v] == '1') {
low[v] = 0;
}
if(low[v] <= high[v]){
for(auto k : to[v]) {
low[k.fi] = min(low[k.fi],k.se);
}
}
}
}
int64 ans = 1;
for(int i = 1 ; i <= N ; ++i) {
ans += high[i] - low[i] + 1;
}
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;

【AtCoder】AGC008的更多相关文章

  1. 【AtCoder】ARC092 D - Two Sequences

    [题目]AtCoder Regular Contest 092 D - Two Sequences [题意]给定n个数的数组A和数组B,求所有A[i]+B[j]的异或和(1<=i,j<=n ...

  2. 【Atcoder】CODE FESTIVAL 2017 qual A D - Four Coloring

    [题意]给定h,w,d,要求构造矩阵h*w满足任意两个曼哈顿距离为d的点都不同色,染四色. [算法]结论+矩阵变换 [题解] 曼哈顿距离是一个立着的正方形,不方便处理.d=|xi-xj|+|yi-yj ...

  3. 【AtCoder】ARC 081 E - Don't Be a Subsequence

    [题意]给定长度为n(<=2*10^5)的字符串,求最短的字典序最小的非子序列字符串. http://arc081.contest.atcoder.jp/tasks/arc081_c [算法]字 ...

  4. 【AtCoder】AGC022 F - Leftmost Ball 计数DP

    [题目]F - Leftmost Ball [题意]给定n种颜色的球各k个,每次以任意顺序排列所有球并将每种颜色最左端的球染成颜色0,求有多少种不同的颜色排列.n,k<=2000. [算法]计数 ...

  5. 【AtCoder】AGC005 F - Many Easy Problems 排列组合+NTT

    [题目]F - Many Easy Problems [题意]给定n个点的树,定义S为大小为k的点集,则f(S)为最小的包含点集S的连通块大小,求k=1~n时的所有点集f(S)的和取模92484403 ...

  6. 【AtCoder】ARC067 F - Yakiniku Restaurants 单调栈+矩阵差分

    [题目]F - Yakiniku Restaurants [题意]给定n和m,有n个饭店和m张票,给出Ai表示从饭店i到i+1的距离,给出矩阵B(i,j)表示在第i家饭店使用票j的收益,求任选起点和终 ...

  7. 【AtCoder】ARC095 E - Symmetric Grid 模拟

    [题目]E - Symmetric Grid [题意]给定n*m的小写字母矩阵,求是否能通过若干行互换和列互换使得矩阵中心对称.n,m<=12. [算法]模拟 [题解]首先行列操作独立,如果已确 ...

  8. 【Atcoder】AGC022 C - Remainder Game 搜索

    [题目]C - Remainder Game [题意]给定n个数字的序列A,每次可以选择一个数字k并选择一些数字对k取模,花费2^k的代价.要求最终变成序列B,求最小代价或无解.n<=50,0& ...

  9. 【Atcoder】AGC 020 B - Ice Rink Game 递推

    [题意]n个人进行游戏,每轮只保留最大的a[i]倍数的人,最后一轮过后剩余2人,求最小和最大的n,或-1.n<=10^5. [算法]递推||二分 [题解]令L(i),R(i)表示第i轮过后的最小 ...

随机推荐

  1. Gradle 如何配置将编译的 JAR 发布到 Archiva 中

    有时候我们希望将我们的jar 开发包发布到 Archiva 中. 如何配置 Gradle 的编译脚本呢? 首先你需要启用 Gradle 的 Maven-publish 插件. plugins { id ...

  2. jenkins 邮件发送错误

    jenkins 在创建新的 Build 的时候希望邮件进行通知. 但是邮件通知的时候出现错误: Unable to Send Mail - javax.net.ssl.SSLException: Un ...

  3. About Grisha N. ( URAL - 2012 )

    Problem Grisha N. told his two teammates that he was going to solve all given problems at the subreg ...

  4. SpringMVC指定webapp的首页

    webapp的首页指的是http://localhost:8080/ 方法一 追加一个[/]URI的请求方法 @Controller public class WelcomeController { ...

  5. git修改下载地址

    git查看远程地址git remote -v修改git remote set-url origin [url]

  6. 安装openssh-server

    以前在服务器上装过openssh-server,今天突然想把台式机也打开ssh服务,结果忘了咋弄,稍微百度了一下就弄好了,备忘一下,以后就不用各种百度了. 第一步,安装openssh-server( ...

  7. 入门display:inline-block运用

    这是我第一篇博客,是我新的开始,我要用博客记录我的学习之旅,在这里我要感谢我的哥哥,他带我开阔了眼界,纠正了我的格局,给我带来了正能量.我是一个小白,学习的路还很长很长,学习了10天HTML与css, ...

  8. Mac 下 brew的卸载 插件

    brew 又叫 Homebrew,是 Mac OSX 上的软件包管理工具,能在 Mac 命令行中方便的安装软件或者卸载软件, 只需要一个命令, 非常方便 brew 类似 ubuntu 系统下的 apt ...

  9. ubantu 安装boost库 c++connector

    安装libmysqlcppconn: sudo apt-get install libmysqlcppconn-dev 安装libboost: sudo apt-get install libboos ...

  10. mysql 中常用的 sql 语句

    SQL分类: DDL-----数据定义语言(CREATE--创建,ALTER--修改. DROP--删除表,DECLARE--声明) DML-----数据定义语言(SELECT--查询,DELECT- ...