Codeforces 1270 H. Number of Components(找性质+线段树)
时间:2020-04-28
本文章向大家介绍Codeforces 1270 H. Number of Components(找性质+线段树),主要包括Codeforces 1270 H. Number of Components(找性质+线段树)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
https://codeforces.com/contest/1270/problem/H
考虑一个联通块一定是一个连续段,可以反证,假设有两段,发现中间的数一定会和两段相连。
那么其实就是要求分界点的个数。
一个分界点可以定义为左边的数全部大于等于右边的数。
那么枚举一个\(v\in a[i]\),把\(\ge v\)的数标记为1,\(< v\)的数标记为0.
因为数互不相同,\(v\)能作为某个地方的分界点,相当于标记后的序列\(11110000\)
也就是相邻的标记不同的个数=1,最左边看作一个1,最右边看作一个0.
记\(f[v]\)的相邻的标记不同的个数。
那么对于修改一个位置的值,可以对\(f\)区间修改。
然后查询\(\sum_{i=1}^n [f[a[i]]=1]\),线段树维护最小值及最小值个数即可。
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int N = 1e6 + 5;
int n, q;
int a[N], b[N][2];
int d[N], d0;
map<int, int> bd;
#define i0 i + i
#define i1 i + i + 1
struct P {
int x, y;
} t[N * 4];
P operator + (P a, P b) {
if(a.x != b.x) return a.x < b.x ? a : b;
return (P) {a.x, a.y + b.y};
}
int lz[N * 4];
int pl, pr, px;
void jia(int i, int v) {
t[i].x += v, lz[i] += v;
}
void down(int i) {
if(lz[i]) {
jia(i0, lz[i]);
jia(i1, lz[i]);
lz[i] = 0;
}
}
void add(int i, int x, int y) {
if(y < pl || x > pr) return;
if(x >= pl && y <= pr) {
jia(i, px); return;
}
int m = x + y >> 1; down(i);
add(i0, x, m); add(i1, m + 1, y);
t[i] = t[i0] + t[i1];
}
void xiu(int i, int x, int y) {
if(y < pl || x > pr) return;
if(x == y) {
t[i].y += px; return;
}
int m = x + y >> 1; down(i);
xiu(i0, x, m); xiu(i1, m + 1, y);
t[i] = t[i0] + t[i1];
}
void Init() {
scanf("%d %d", &n, &q);
fo(i, 1, n) scanf("%d", &a[i]), d[++ d0] = a[i];
fo(i, 1, q) {
scanf("%d %d", &b[i][0], &b[i][1]);
d[++ d0] = b[i][1];
}
sort(d + 1, d + d0 + 1);
d0 = unique(d + 1, d + d0 + 1) - (d + 1);
fo(i, 1, d0) bd[d[i]] = i;
}
void gai(int x, int xs) {
if(x == 0) {
pl = a[x + 1], pr = d0, px = xs;
add(1, 1, d0);
} else
if(x == n) {
pl = 1, pr = a[x] - 1; px = xs;
add(1, 1, d0);
} else {
if(a[x] != a[x + 1]) {
pl = a[x], pr = a[x + 1];
if(pl > pr) swap(pl, pr);
pr --; px = xs;
add(1, 1, d0);
}
}
}
int cnt[N];
void add_cnt(int x, int xs) {
if(xs == 1) {
if(++ cnt[x] == 1) {
pl = pr = x; px = 1;
xiu(1, 1, d0);
}
} else {
if(-- cnt[x] == 0) {
pl = pr = x; px = -1;
xiu(1, 1, d0);
}
}
}
void build() {
fo(i, 1, n) {
a[i] = bd[a[i]];
add_cnt(a[i], 1);
}
fo(i, 0, n) gai(i, 1);
}
void work() {
fo(i, 1, q) {
int x, y;
x = b[i][0], y = b[i][1];
y = bd[y];
add_cnt(a[x], -1);
gai(x - 1, -1); gai(x, -1);
a[x] = y;
add_cnt(a[x], 1);
gai(x - 1, 1); gai(x, 1);
pp("%d\n", t[1].x == 1 ? t[1].y : 0);
}
}
int main() {
Init();
build();
work();
}
原文地址:https://www.cnblogs.com/coldchair/p/12794384.html
- 推荐[搜索引擎架构]的几篇文章
- 中小型商城系统中的分类/产品属性/扩展属性的数据库设计
- Linux下FTP虚拟账号环境部署总结
- Replace方法与正则表达式的性能比较
- 由索引节点(inode)爆满引发的问题
- As3.0中的位图(Bitmap/BitmapData)编程
- Mesos+Zookeeper+Marathon的Docker管理平台部署记录(2)--负载均衡marathon-lb
- Docker集群管理工具-Kubernetes部署记录
- AS3:小游戏“贪吃蛇”的实现
- 超实用的8个Linux命令行性能监测工具
- 用javascript替换URL中的参数值
- Gitblit版本服务器环境部署记录
- HDK扩展自定义VEX函数print
- AsyncTask和Handler对比
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法