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. leetcode解题报告(8):Remove Element

    描述 Given an array and a value, remove all instances of that value in place and return the new length ...

  2. P3979 遥远的国度 树剖

    P3979 遥远的国度 树剖 题面 需要想一下的树剖题,对于询问三需要处理换跟后的情况.我们以1为树根跑一遍剖分,对于换跟进行分类讨论,算出实际答案.讨论有三种情况: (以1为树根的树上) 跟在询问节 ...

  3. idea快捷方式1

    Ctrl+Alt+O 优化导入的类和包 Alt+Insert 生成代码(如get,set方法,构造函数等)   或者右键(Generate) fori/sout/psvm + Tab Ctrl+Alt ...

  4. Django-中间件实现1分钟内只允许三次访问

    代码 class Throttle(MiddlewareMixin): def process_request(self, request): # 1. 拿到用户请求的IP # print(reque ...

  5. Ubuntu 在VirtualBox里无法联网【已解决】

    1. 在virtualBox中设置网络:设置->网络->将连接方式选定为“网络地址转换(NAT)” 点确定 2.进入Ubuntu系统中:系统设置->网络, 在弹出的对话框中选择:有线 ...

  6. mysql—并发控制及事务

    并发控制 实现的并发访问的控制技术是基于锁: 锁分为表级锁和行级锁,MyISAM存储引擎不支持行级锁:InnoDB支持表级锁和行级锁: 锁的分类有读锁和写锁,读锁也被称为共享锁,加读锁的时候其他的人可 ...

  7. java课后实验性问题4

    课后作业一: 使用类的静态字段和构造函数,我们可以跟踪某个类所创建对象的个数.请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象? 设计思路:定义类的构造函数时使静态变量i进行i++,即每构 ...

  8. mongoose 安装及配置

    MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方>案.MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据 ...

  9. Flutter子组件调用父组件方法修改父组件参数

    子组件调用父级组件方法的主要实现是父组件给子组件传入一个方法,然后在子组件中调用父级方法来修改父级的参数.看一下效果图 父级组件实现 在父级组件中写一个_editParentText的方法来修改组件中 ...

  10. QT 自定义消息

    #define TEST_EVENT QEvent::User + 100   class CVxActuatorMain : public QMainWindow {   protected:    ...