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. webpack+vue+Eslint+husky+lint-staged 统一项目编码规范

    一. Eslint: 为什么我们要在项目中使用ESLint ESLint可以校验我们写的代码,给代码定义一个规范,项目里的代码必须按照这个规范写. 加入ESLint有非常多的好处,比如说可以帮助我们避 ...

  2. 【概率论】3-7:多变量分布(Multivariate Distributions Part I)

    title: [概率论]3-7:多变量分布(Multivariate Distributions Part I) categories: Mathematic Probability keywords ...

  3. DUILib学习笔记---消息处理

    WIN32下窗口消息循环 MSG msg = { 0 }; while( ::GetMessage(&msg, NULL, 0, 0) ) { ::TranslateMessage(& ...

  4. scrapy框架之items项目

    Items 主要目标是从非结构化来源(通常是网页)提取结构化数据.Scrapy爬虫可以将提取的数据作为Python语句返回.虽然方便和熟悉,Python dicts缺乏结构:很容易在字段名称中输入错误 ...

  5. docker数据持久化

    转载/参考: https://www.jianshu.com/p/ef0f24fd0674 Docker的数据持久化主要有两种方式: bind mount docker managed volume ...

  6. Redis字符串(String)

    1.set SET key value [EX seconds] [PX milliseconds] [NX|XX] 将字符串值 value 关联到 key 可选参数: EX second :设置键的 ...

  7. 20182332 实验一《Linux基础与Java开发环境》实验报告

    20182332 实验一<Linux基础与Java开发环境>实验报告 课程:<程序设计与数据结构> 班级: 1823 姓名: 盛国榕 学号:20182332 实验教师:王志强 ...

  8. DBCA创建数据库

    工具/原料 oracle database 11g 步骤/方法 1 确保安装好oracle database 11g 2 打开命令提示符(运行中输入CMD打开 或是在 附件中点击打开) 3 输入dbc ...

  9. What do you do as a DevOps?

    https://ilhicas.com/2019/08/11/What-you-as-a-Devops.html Introduction In this post I'll just explain ...

  10. in mind (不是 切记 的意思)

    Both Grunt and Gulp.js perform these automation tasks particularly well, although Gulp.js has the ed ...