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. tarjan模板(带注释)

    //dfsn[x]记录x节点有没有被访问过,有,则是第几个 //lowlink[x]记录x能到的祖先中编号最小的 //dfs_clock是个编号累计器 //scc记录一个 inline void df ...

  2. 收藏加备用。ext.xfs文件系统 文件恢复

    注意 当确认误删除文件后立刻使用各种方式阻止新数据在写入该分区了. 设置只读或umount都可以 ext2 3 4 文件系统 可以用 extundelete 这个工具来恢复. github地址: ht ...

  3. Flask-第三方插件

    Flask-Session 因为flask自带的session是将session存在cookie中: 所以才有了第三方Flask_session插件,可以将session存储在我们想存储的数据库中(r ...

  4. easyui复选框实现单选框

    $(':checkbox[name=primary_key_flag]').each(function(){ $(this).click(function(){ if(this.checked){ $ ...

  5. 字符串匹配(KMP&BF)

    字符串匹配   题目描述 设计一个程序,从一个主字符串中查找一个子字符串在主串中第一次出现的位置.主串和子串的长度不超过100.如果找不到,则输出-1. 程序输入说明 第一行输入一个整数N,说明需要进 ...

  6. 【java】Java.math.BigDecimal.subtract()方法实例

    java.math.BigDecimal.subtract(BigDecimal subtrahend) 返回一个BigDecimal,其值为 (this - subtrahend), 精度为 max ...

  7. 分享一个seata demo,讲两个个问题

    Seata,阿里开源的分布式事务框架,多的我就不介绍了,了解详细介绍,请看官网.seata spring boot入门,可以看我上一篇博客<Spring boot微服务如何集成fescar解决分 ...

  8. RAD,Eclipse切換界面語言(中日英)

    找到RAD的EXE的位置: 右鍵→屬性→Link先(Target) 將原來的"C:\Program Files\IBM\SDP\eclipse.exe" -product com. ...

  9. nginx配置不当引起的错误

    1.CRLF注入 1.1环境配置 apt install nginx vi /etc/nginx/sites-available/default location / { return 302 htt ...

  10. Angular4.x+Ionic3 踩坑之路之打包时出现JAVASCRIPT HEAP OUT OF MEMORY的几种解决办法

    最近开发的一个比较大型的App时打生产环境包是出现内存不足导致打包失败的问题.然后百度发现解决方法都是一样,自己试了一下都没什么暖用,心里只想用呵呵来形容了.最后经朋友介绍,技术问题还得去谷歌,git ...