A Accurate Movement

签到

M Managing Difficulties

签到

B Bad Treap

已知\(y=\sin(x)\),要求给出数组\(a[n]\),满足\(\forall i,j\in[1,n],a[i]\neq a[j]\),都有\(\sin(a[i])\neq \sin(a[j])\)。

这里又一种不怎么玄的写法,就是我们找到一个整数\(x\),\(sin(x)\)非常非常小并且\(\sin(x)>0\),这样算,嗯……例如\(sin(2x)\)的时候,\(\sin(2x)=2\sin x \cos x\),它的值只会有很小的增加\((2\cos x<2)\)。然后就算它扩大了\(2.5\times10^4\)倍之后,仍然都增加不到接近1的位置,那么我们就成功了。然后因为\(\sin x\)关于原点对称,在负半轴把它对称过去,仍然是一个递增序列。

int n;
const int N = 5e4 + 5;
int a[N]; int main(void){
scanf("%d", &n);
double mn = 100;
int id = 1;
for (int i=1;i<=4e4;++i){
if (sin(i) < mn && sin(i) > 0){
mn = sin(i), id = i;
}
} for (int i=-25000;i<=25000;++i){
a[i + 25000] = i * id;
}
for (int i=0;i<n;++i){
printf(i==n-1?"%d\n":"%d ", a[i]);
} return 0;
}

不对称过去会wa7,(露西亚,你太baby辣)

I Ideal Pyramid

给定\(n\)个方尖碑,要用一个仰角为45°的金字塔把它们全部覆盖起来,也就是建成金字塔之后,所有的方尖碑都会被它掩盖,高度也不会穿过金字塔,问金字塔应该建在哪里,高度最小为多少。

实际上,所有的四棱锥都可以转化为一个正方形的覆盖,那么题意就转化为了,找到一个最小的正方形,可以包括所有的正方形的集合。这样的话,直接维护正方形集合的上下左右边界(最后得到一个矩形),再按照矩形的中心扩展即可。

int n;
const int N = 1000 + 5; void solve(){
n = read();
ll x, y, h;
ll L = 1e18, R = -1e18, U = -1e18, D = 1e18;
for (int i=1;i<=n;++i){
x = read(), y = read(), h = read();
L = min(L, x - h), R = max(R, x + h), U = max(U, y + h), D = min(D, y - h);
}
ll a = (L + R) / 2, b = (U + D) / 2, H = max((R - L + 1) / 2, (U - D + 1) / 2);
printf("%lld %lld %lld\n", a, b, H);
} int main(void){
int T;
// T = read();
T = 1;
while (T--){
solve();
} return 0;
}

King's Children

有一个\(n\times m\)的网格,里面有最多\(A~to ~Z\)个孩子,king要把这个网格分成若干矩形,要满足:

  • 每个矩形必须精确的包括一个孩子
  • 每个格子都必须精确的属于1个矩形(也就是矩形不相交的分完整个大网格)
  • 包括了\(A\)的矩形的面积尽可能大

数据范围\(1\leq n,m\leq 1000\)

这题可以用悬线法,也可以用单调栈(不如说悬线法就是单调栈的一个子集问题)

算是比较经典的求最大子矩形的问题,然而我不会,下面先介绍一下悬线法。


悬线法

oi-wiki的定义:https://oi-wiki.org/misc/hoverline/

一个简单的题目,简单理解悬线法的过程:

SP1805 Largest Rectangle in a Histogram

https://www.luogu.com.cn/problem/SP1805

首先,\(n\)个矩形就相当于\(n\)条悬线,我们知道最大的面积肯定是由某一个悬线向左右扫过而形成的。那么悬线的扩展,显然的满足某一递推关系,可以帮助我们将复杂度由原来的\(O(N^2)\)变成\(O(N)\)。

定义\(l_i\)为当前的\(i\)位置能扩展到的悬线的最左端,初始时\(l_i=i\)。假设已经处理好了前\(i-1\)个位置的答案,那么当\(h_i\leq h_{i-1}\)时,\(i\)也能扩展到\(i-1\)能扩展到的位置。如果\(h_i\leq h_{l_{i-1}-1}\)时,又可以接着往前扩展……直到扩展到边界,我们就停止。因此对于\(\forall i\),我们有

while (L[i] > 1 && a[i] <= a[L[i] - 1]) L[i] = L[L[i] - 1];

同样的,假如我们已经处理好\(i+1\)到\(n\)的答案,\(r_i\)也能不断的向右扩展。

while (R[i] < n && a[i] <= a[R[i] + 1]) R[i] = R[R[i] + 1];

那么完整代码:

int n;
const int N = 1e5 + 5;
int a[N], L[N], R[N]; void solve(){
for (int i=1;i<=n;++i){
scanf("%d", &a[i]);
L[i] = R[i] = i;
}
for (int i=1;i<=n;++i){
while (L[i] > 1 && a[i] <= a[L[i] - 1]) L[i] = L[L[i] - 1];
}
for (int i=n;i>=1;--i){
while (R[i] < n && a[i] <= a[R[i] + 1]) R[i] = R[R[i] + 1];
}
ll res = 0;
for (int i=1;i<=n;++i){
res = max(res, 1LL * a[i] * (R[i] - L[i] + 1));
}
printf("%lld\n", res);
}

UVA1619/POJ2796 Feel Good

给出长度为\(n\)的数组\(a[n]\),找到一个子区间,使得子区间内的最小值与区间内所有元素和的乘积最大,如果有多个答案,输出长度最小的答案,如果仍有多个答案,输出最左端序号最小的答案。

枚举这个最小值,它一旦向左右扩展,就肯定会增加这个乘积的值,这样的话,又变成了一个悬线法求最大子矩形的问题。

数据范围:\(1\leq n \leq 10^5\) 我恨UVA的多组数据和格式

int n;
const int N = 1e5 + 5;
int a[N], L[N], R[N];
ll pre[N];
bool fst = 1; void solve(){
// n = read();
if (!fst){
puts("");
}
fst = 0;
for (int i=1;i<=n;++i){
a[i] = read();
pre[i] = pre[i - 1] + a[i];
L[i] = R[i] = i;
}
for (int i=1;i<=n;++i){
while (L[i] > 1 && a[i] <= a[L[i] - 1]) L[i] = L[L[i] - 1];
}
for (int i=n;i>=1;--i){
while (R[i] < n && a[i] <= a[R[i] + 1]) R[i] = R[R[i] + 1];
} ll res = 0;
int aL = 1, aR = 1;
for (int i=1;i<=n;++i){
ll cur = (pre[R[i]] - pre[L[i] - 1]) * a[i];
if (cur > res){
res = cur, aL = L[i], aR = R[i];
}
else if (cur == res){
if (R[i] - L[i] < aR - aL){
aL = L[i], aR = R[i];
}
else if (R[i] - L[i] == aR - aL){
if (L[i] < aL){
aL = L[i], aR = R[i];
}
}
}
}
printf("%lld\n%d %d\n", res, aL, aR);
} int main(void){
while (~scanf("%d", &n)){
if (n == 0){
puts("");
}
else solve();
}
return 0;
}

最大子矩形:p4147 玉蟾宫

嗯……差不多捏,问题。oiwiki留的课后习题也写了,就不放出来了。


那么正式说K,K题我的思路就是,每个矩形都用悬线法进行选取和填充。但是,由于填充顺序的不同,有极低的概率出现最后有矩形没有被完全填上的情况,因此做一个简单的check,如果填充错误,则随机化顺序,重新填充答案。大概2~3次随机后就不可能出现还没填充的情况了,所以这个复杂度是完全可行的。

代码:

int n, m, sx, sy;
const int N = 1000 + 5;
char s[N][N], ss[N][N];
int U[N], L[N], R[N];
struct node{
char ch;pii cor;
};
vector<node> alp; bool check(pii s, pii a, pii b){
return (s.xx >= a.xx && s.xx <= b.xx) && (s.yy >= a.yy && s.yy <= b.yy);
} void putin(char ch, pii cor){
int res = 0; pii r1 = cor, r2 = cor;
for (int j=1;j<=m;++j) U[j] = 0;
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
if (s[i][j] == '.' || s[i][j] == ch){
U[j]++;
}
else{
U[j] = 0;
}
L[j] = R[j] = j;
}
for (int j=1;j<=m;++j){
while (L[j] > 1 && U[j] <= U[L[j] - 1]) L[j] = L[L[j] - 1];
}
for (int j=m;j>=1;--j){
while (R[j] < m && U[j] <= U[R[j] + 1]) R[j] = R[R[j] + 1];
}
for (int j=1;j<=m;++j){
int cur = U[j] * (R[j] - L[j] + 1);
pii c1 = pii(i - U[j] + 1, L[j]), c2 = pii(i, R[j]);
if (cur > res && check(cor, c1, c2)){
res = cur, r1 = c1, r2 = c2;
}
}
}
for (int i=r1.xx;i<=r2.xx;++i){
for (int j=r1.yy;j<=r2.yy;++j){
if (s[i][j] == '.'){
s[i][j] = 'a' + (ch - 'A');
}
}
}
} void solve(){
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
s[i][j] = ss[i][j];
}
}
int alen = alp.size(), t = alen - 1;
if (alen > 1){
for (int i=0;i<alen-1;++i){
int x = 1 + rand() % t;
swap(alp[x], alp[t]);
t--;
}
} for (int i=0;i<alp.size();++i){
putin(alp[i].ch, alp[i].cor);
} } bool isOK(){
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
if (s[i][j] == '.'){
return false;
}
}
}
return true;
} int main(void){
srand(time(NULL));
int T;
T = 1;
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
cin >> ss[i][j];
if (ss[i][j] == 'A'){
alp.push_back(node{'A', pii(i, j)});
}
}
}
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
if (ss[i][j] != '.' && ss[i][j] != 'A'){
alp.push_back(node{ss[i][j], pii(i, j)});
}
}
}
do{
solve();
}while(!isOK());
for (int i=1;i<=n;++i){
for (int j=1;j<=m;++j){
cout << s[i][j];
}
cout << endl;
} return 0;
}

E Equidistant

给出一个树,判断是否有一个结点,满足到所有特殊点的距离相等。

数据范围:\(1\leq m,n\leq 2\times 10^5\)。

这题感觉用多源bfs更简单……嗯……用树形DP试着写写吧。

树形DP 不推荐。。。。

int n, m;
const int N = 2e5 + 5, INF = 1e9 + 10;
bool st[N], ok;
vector<int> ve[N];
int f[N], g[N]; void dfs(int u, int pre){
for (auto to : ve[u]){
if (to == pre) continue;
dfs(to, u);
f[u] = min(f[u], f[to] + 1);
g[u] = max(g[u], g[to] + 1);
}
} void dfs2(int u, int pre){
if (ok) return;
if (f[u] == g[u]){
if (!ok){
puts("YES");
printf("%d\n", u);
}
ok = true;
return ;
}
int mx1 = -INF, mx2 = -INF, mn1 = INF, mn2 = INF;
if (st[u]){
mx1 = mn1 = 0;
}
for (auto to : ve[u]){
if (f[to] + 1 < mn1){
mn2 = mn1, mn1 = f[to] + 1;
}
else if (f[to] + 1 < mn2){
mn2 = f[to] + 1;
}
if (g[to] + 1 > mx1){
mx2 = mx1, mx1 = g[to] + 1;
}
else if (g[to] + 1 > mx2){
mx2 = g[to] + 1;
}
}
for (auto to : ve[u]){
if (to == pre) continue;
int fto = f[to], gto = g[to];
if (f[u] == f[to] + 1){
f[u] = mn2;
f[to] = min(f[to], mn2 + 1);
}
else{
f[to] = min(f[to], f[u] + 1);
}
if (g[u] == g[to] + 1){
g[u] = mx2;
g[to] = max(g[to], mx2 + 1);
}
else g[to] = max(g[to], g[u] + 1);
dfs2(to, u);
f[u] = mn1, g[u] = mx1;
f[to] = fto, g[to] = gto;
}
} int main(void){
n = read(), m = read();
for (int i=1;i<=n;++i){
f[i] = INF, g[i] = -INF;
}
int u, v, x;
for (int i=1;i<n;++i){
u = read(), v = read();
ve[u].push_back(v), ve[v].push_back(u);
}
for (int i=1;i<=m;++i){
x = read(), st[x] = true;
f[x] = g[x] = 0;
} dfs(1, 0);
dfs2(1, 0); if (!ok){
puts("NO");
} return 0;
}

CF102411 ICPC 2019-2020 North-Western Russia Regional Contest题解的更多相关文章

  1. 2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest

    2017 ACM - ICPC Asia Ho Chi Minh City Regional Contest A - Arranging Wine 题目描述:有\(R\)个红箱和\(W\)个白箱,将这 ...

  2. ICPC 2019-2020 North-Western Russia Regional Contest

    目录 Contest Info Solutions Problem A. Accurate Movement Problem B. Bad Treap Problem E. Equidistant P ...

  3. ICPC Central Russia Regional Contest (CRRC 19)题解

    题目连接:https://codeforces.com/gym/102780 寒假第二次训练赛,(某菜依旧是4个小时后咕咕咕),战况还行,个人表现极差(高级演员) A:Green tea 暴力枚举即可 ...

  4. 05.24 ICPC 2019-2020 North-Western Russia Regional Contest复现赛+Codeforces Round #645 (Div. 2)

    A.Accurate Movement(复现赛) 题意:两个木块最左边都在0的位置,最右边分别为a,b(b>a),并且短的木条只能在长木条内移动,问两个木条需要移动多少次才能使两个木条的右端都在 ...

  5. 2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest

    目录 Contest Info Solutions A. Berstagram B. The Feast and the Bus C. Trip to Saint Petersburg E. The ...

  6. 2019-2020 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules, Teams Preferred)【A题 类型好题】

    A. Berstagram Polycarp recently signed up to a new social network Berstagram. He immediately publish ...

  7. 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) D. Firecrackers (贪心,二分)

    题意:有个长度为\(n\)的监狱,犯人在位置\(a\),cop在位置\(b\),你每次可以向左或者向右移动一个单位,或者选择不动并在原地放一个爆竹\(i\),爆竹\(i\)在\(s[i]\)秒后爆炸, ...

  8. 2020-2021 ICPC, NERC, Southern and Volga Russian Regional Contest (Online Mirror, ICPC Rules) C. Berpizza (STL)

    题意:酒吧里有两个服务员,每个人每次都只能服务一名客人,服务员2按照客人进酒吧的顺序服务,服务员3按照客人的钱来服务,询问\(q\),\(1\)表示有客人进入酒吧,带着\(m\)块钱,\(2\)表示询 ...

  9. The 2013 South America/Brazil Regional Contest 题解

    A: UVALive 6525 cid=61196#problem/A" style="color:blue; text-decoration:none">Atta ...

  10. ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków

    ACM ICPC Central Europe Regional Contest 2013 Jagiellonian University Kraków Problem A: Rubik’s Rect ...

随机推荐

  1. web3 产品介绍: safe --多签钱包 多人审批更放心

    Safe是一款由Gnosis团队开发的多签钱包,它提供了一种安全.灵活和易于使用的方式来管理加密资产.在本文中,我们将介绍Safe的主要特点以及如何使用Safe来保护您的数字资产. 一.Safe的特点 ...

  2. 【Git】GithubDesktop 忽略文件无法忽略BUG

    问题描述: 从仓库拉取的[.gitignore]忽略配置文件,在项目跑起来之后会生成诸多.idea文件,target打包文件 一开始没有忽略,但是发现使用GD配置之后忽略无效: 解决办法: 做一次随便 ...

  3. 【RabbitMQ】04 路由模式

    在订阅模式的基础上制定一些特定发送规则 创建路由模式的生产者: 注意这些变化,跟之前的订阅模式并不一样 package cn.dzz.routineQueueInProducer; import co ...

  4. 再测python3.13a —— python3.13是否移除了GIL的限制(续)

    前文: python3.13是否移除了GIL的限制 x86_64 ubuntu22.04环境下编译版本python3.13.0 alpha 0源码--python3.13.0 alpha 0的源码编译 ...

  5. MindSpore1.3.0 GPU pip方式安装 —— Ubuntu18.04系统 (最终安装结果为成功)需要管理员权限,sudo安装

    官网地址: https://www.mindspore.cn/install =========================================================== 安 ...

  6. 解决CGLib动态代理测试不通过-Unable to load cache item

    1.背景 在学习aop底层时遇到的问题,做个小结 2.现象 动态代理代码如下: package com.ldp.proxy; import net.sf.cglib.proxy.Enhancer; i ...

  7. 删库了不用跑路!binlog恢复数据实操

    各位道友大家好呀! 想必道友们或多或少都听说过MySQL的binlog的作用,它记录了数据库整个的生命周期,可用于恢复数据或者从库同步数据. 那么如果发生了数据库误删,具体该怎样恢复数据呢? 下面就以 ...

  8. CKS考试心得分享

    CKS证书 考试相关 考试报名准备 CKS考试和CKA考试一样,已经开放中国大陆的考试.但区别是CKS目前没有中文题目,考试都是英文题目,唯一区别是CKS中文考试是中文老师监考,仅此而已.因此,建议C ...

  9. SMU Spring 2023 Contest Round 7

    A. Programming Contest 签到题. 输入输出读完应该就懂了: 从y1枚举到y2,若枚举的年份不在停办年份里则答案加一 void solve() { int n,m; cin > ...

  10. stm32g070 usart 中断问题: 开启接收中断 RXNEIE 需要注意ISR的错误类型,否则会进入中断。

    usart 中断问题: 开启接收中断 RXNEIE 需要注意ISR的错误类型,否则会进入中断. 调试时发现,如果ISR的ORE和FE置位,而此时要是使能RX中断(RXNEIE置位)就会进入中断复位程序 ...