AGC007

A - Shik and Stone

如果i + j走过的格子只有一个,那么就是可以走到

#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 H,W,cnt[30];
char s[15][15];
bool vis[15][15];
void Solve() {
read(H);read(W);
for(int i = 1 ; i <= H ; ++i) {
scanf("%s",s[i] + 1);
}
for(int i = 1 ; i <= H ; ++i) {
for(int j = 1 ; j <= W ; ++j) {
if(s[i][j] == '#') {
++cnt[i + j];
if(cnt[i + j] >= 2) {puts("Impossible");return;}
}
}
}
puts("Possible");
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

B - Construct Sequences

把a标成\(i*N\)

把b标成\((N - i + 1) * N\)

此时a和b按位相加后相等,然后按照排列的顺序,给第一个排列所在的b加0,第二个+1,第三个+2...就可以了

#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 205
//#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 a[20005],b[20005],p[20005];
void Solve() {
read(N);
for(int i = 1 ; i <= N ; ++i) read(p[i]);
for(int i = 1 ; i <= N ; ++i) {b[i] = (N - i + 1) * N; a[i] = i * N;}
for(int i = 1 ; i <= N ; ++i) {
b[p[i]] += i - 1;
}
for(int i = 1 ; i <= N ; ++i) {
out(a[i]);space;
}
enter;
for(int i = 1 ; i <= N ; ++i) {
out(b[i]);space;
}
enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

C - Pushing Balls

这个需要注意到,当我们一个球进洞后,其余的球还是原来的形态,且差距\(d_{i}\)仍然是一个等差数列

我们每次的期望就是\(\frac{2nd + 2n(2n - 1)x/2}{2n} = d + (2n - 1)x / 2\)

推一下式子发现新的首项是

\(d' = (n + 1)d/ n + 5x /2n\)

\(x' = (n + 2)x / n\)

然后\(n - 1\),继续计算

#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 205
//#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;
db d,x;
void Solve() {
read(N);
scanf("%lf%lf",&d,&x);
db ans = 0;
while(N) {
ans += d + (2 * N - 1) / 2.00 * x;
d = 1.0 * (N + 1) / N * d + 5 * x / (2 * N);
x = 1.0 * (N + 2) / N * x;
--N;
}
printf("%.10lf\n",ans);
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

D - Shik and Game

相当于除掉我必须从0走到1的点,我在上面需要绕几个环

很显然,环是互相分离的,因为如果环的最靠前一个点有钱,走回去的路上钱都会被捡起来

这样就很容易dp了,我们可以把E去掉,求附加的最小时间

设\(dp[i]\)表示走到i且i的钱被捡完了的最小附加时间

如果从前面一个\(j\)转移过来,若\(2(x[i] - x[j]) >= T\),那么这一圈的附加时间应该是\(2(x[i] - x[j])\),否则应该是T

这两个分别可以用前缀最小值和单调队列维护,复杂度\(O(n)\)

#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 205
//#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 dp[100005],pre;
int64 T,E;
int64 x[100005];
int N,p;
deque<int> que;
void Solve() {
read(N);read(E);read(T);
for(int i = 1 ; i <= N ; ++i) {read(x[i]);dp[i] = i * T;}
p = -1;pre = 1e18;
que.push_back(0);
for(int i = 1 ; i <= N ; ++i) {
while(p < i - 1 && 2 * (x[i] - x[p + 2]) > T) {
++p;pre = min(pre,dp[p] - 2 * x[p + 1]);
}
dp[i] = min(dp[i],pre + 2 * x[i]);
while(!que.empty() && 2 * (x[i] - x[que.front() + 1]) > T ) {que.pop_front();}
if(!que.empty()) {
dp[i] = min(dp[i],dp[que[0]] + T);
}
while(!que.empty() && dp[que.back()] > dp[i]) que.pop_back();
que.push_back(i);
}
out(dp[N] + E);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

E - Shik and Travel

我们记录一个点对为这棵子树中往上延伸的两条链长度\((a,b)\)我们合并的时候用两个子树里的\((a,b)\)和\((c,d)\)合并,二分答案来限制合并的链长不超过某个值

合并的时候用含点对少的和含点对多的合并,新合出来的不会超过点对少的的两倍,少的中每一个点对\((a,b)\)可以找到\((a,u)\),u是另一棵树能合出来最小的,b同理

这样就可以做了

#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);
}
int N;
int64 val[MAXN],lim,pre[MAXN];
vector<int> son[MAXN];
vector<pair<int64,int64> > v[MAXN];
vector<pair<int64,int64> > tmp,ano;
bool flag = 0;
void dfs(int u) {
if(flag) return;
v[u].clear();
if(son[u].size() == 0) {v[u].pb(mp(0,0));return;}
dfs(son[u][0]);dfs(son[u][1]);
int a = son[u][0],b = son[u][1];
if(v[a].size() > v[b].size()) swap(a,b);
tmp.clear();ano.clear();
for(auto t : v[a]) {
tmp.pb(mp(t.fi,t.se));tmp.pb(mp(t.se,t.fi));
}
sort(tmp.begin(),tmp.end());
for(auto t : v[b]) {
ano.pb(mp(t.fi,t.se));ano.pb(mp(t.se,t.fi));
}
sort(ano.begin(),ano.end());
int r = ano.size() - 1;
pre[0] = ano[0].se;
for(int i = 1 ; i < ano.size() ; ++i) pre[i] = min(pre[i - 1],ano[i].se);
for(auto t : tmp) {
while(r >= 0 && ano[r].fi + val[b] + t.fi + val[a] > lim) --r;
if(r >= 0) {
v[u].pb(mp(pre[r] + val[b],t.se + val[a]));
}
}
if(!v[u].size()) flag = 1;
return;
}
bool check(int64 mid) {
lim = mid;
flag = 0;dfs(1);
if(flag) return false;
return true;
}
void Solve() {
read(N);
int a;
for(int i = 1 ; i < N ; ++i) {
read(a);
son[a].pb(i + 1);read(val[i + 1]);
}
int64 L = 0,R = 1e16;
while(L < R) {
int64 mid = (L + R) >> 1;
if(check(mid)) {
R = mid;
}
else L = mid + 1;
}
out(L);enter;
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

F - Shik and Copying String

我们先对每个点找一个匹配点,这个点就是\(t[i] == s[j]\)且j最小的位置

且对于i的匹配点必须是递增的

然后我们相当于从每个匹配点在一个高度无限,宽度为字符串长度,开始每步第一次可以往下走,然后往右走,直到走到匹配的最后一个位置

我们要求的就是这列路径的最大高度

从后往前开始递推,遇到一个结束位置,高度加1,而且所有的下降位置需要+1

如果这一列位置是个下降位置,上面还有c条线,我可以拖到i - c的位置再下降(咕咕咕是人类的本质)

#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 1000005
//#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;
char s[MAXN],t[MAXN];
int pos[MAXN],suf[MAXN],to[MAXN],turn[MAXN];
void Solve() {
read(N);
scanf("%s",s + 1);
scanf("%s",t + 1);
bool f = 1;
for(int i = 1 ; i <= N ; ++i) {
if(s[i] != t[i]) {f = 0;break;}
}
if(f) {puts("0");return;}
int p = N;
for(int i = N ; i >= 1 ; --i) {
p = min(p,i);
while(p >= 1 && s[p] != t[i]) --p;
if(p == 0) {puts("-1");return;}
if(!pos[p]) pos[p] = i;
to[i] = p;
}
int cnt = 0,t = 0;
int ans = 0;
for(int i = N ; i >= 1 ; --i) {
suf[i] = suf[i + 1];
if(pos[to[i]] == i) {
++suf[i];++cnt;++t;
}
ans = max(suf[i],ans);
if(pos[i]) {
--cnt;
turn[i - cnt + t]++;
}
suf[i] -= turn[i + t];turn[i + t] = 0;
}
out(ans);enter;
} int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Solve();
return 0;
}

【AtCoder】AGC007的更多相关文章

  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解题报告(4):Search in Rotated Sorted ArrayII

    描述 Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would t ...

  2. vue pdf下载

    主要技术栈是Vue,两个库: html2canvas npm地址 jspdf 具体实现代码如下: <template> <div class="priview_resume ...

  3. JAVA基础知识|小知识点

    1.强烈建议,不使用char类型 那么,到底为什么java里不推荐使用char类型呢?其实,1个java的char字符并不完全等于一个unicode的字符.char采用的UCS-2编码,是一种淘汰的U ...

  4. puppeteer爬虫服务

    爬虫文件 baidu.js const puppeteer = require("puppeteer"); const path = require('path'); const ...

  5. JAVA安全漫谈1-8笔记

    一.反射篇1 classloader就是java的类加载器,告诉虚拟机如何加载这个类.默认情况下根据类名来加载类,类名必须是完整路径 public class class_init { { Syste ...

  6. Sql中truncate,delete以及drop的比较

    相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 2.drop.truncate都是DDL语句(数据定义语言),执行后会自动提交. 不同点: 1. t ...

  7. 性能调优 | 如何通过性能调优突破 MySQL 数据库性能瓶颈?

    本文出自头条号老王谈运维,转载请说明出处. MySQL 数据库瓶颈对 DBA 程序员而言,是非常棘手的问题.要正确的优化SQL,我们需要快速定位能性的瓶颈点,也就是说快速找到我们SQL主要的开销在哪里 ...

  8. 文件转移 互联网组成 路由器 分组交换 交换机 冲突域 网卡 数据帧的发送与接收会带来CPU开销 CPU中断 双网卡切换

    https://zh.wikipedia.org/zh-cn/网段 在以太网环境中,一个网段其实也就是一个冲突域(碰撞域).同一网段中的设备共享(包括通过集线器等设备中转连接)同一物理总线,在这一总线 ...

  9. ubuntu 上开发.netcore

    ubuntu需要安装的软件: 1.sudo apt-get install openssh-server openssh-client 2.sudo apt-get git 3.安装vscode 4. ...

  10. OpenCV学习笔记(2)——如何用OpenCV处理视频

    如何用OpenCV处理视频 读取视频文件,显示视频,保存视频文件 从摄像头获取并显示视频 1.用摄像头捕获视频 为了获取视频,需要创建一个VideoCapature对象.其参数可以是设备的索引号,也可 ...