HDU4747:Mex(线段树区间修改)
题意:
给出\(n\)个数,然后求\(\sum_{i=1}^n\sum_{j=i}^nmex(i,j)\)。\(mex(i,j)\)表示区间\([i,j]\)的\(mex\)。
思路:
- 考虑枚举左右端点的其中一个,然后快速统计答案。
- 观察发现对于一个\(a_i\),如果区间左端点从包含它到了不包含的状态,那么其会影响\([i+1,next[a_i]-1]\)这个区间中的\(mex\)值。
- 那么尝试枚举左端点,根据左端点数值快速统计答案。(一开始想的右端点半天出不来啊= ,=)
- 怎么统计呢?
- 观察到左端点固定的话,区间\(mex\)是单调不减的,那么我们就利用这一性质!
- 找到右端点位于\([i+1,next[a_i]-1]\)时,区间\(mex\)大于\(a_i\)的集合,然后区间修改即可。
总的来说,主要还是要分析到一个点对区间\(mex\)的影响,以及区间\(mex\)的单调性。
#include <bits/stdc++.h>
//#define heyuhhh ok
using namespace std;
typedef long long ll;
const int N = 200005;
int a[N], b[N];
int n;
bool vis[N];
ll sumv[N << 2], lz[N << 2], maxv[N << 2];
int nxt[N];
void Getmex() {
map <int, int> mp;
int j = 0;
for(int i = 0; i <= n + 1; i++) vis[i] = 0;
for(int i = 1; i <= n; i++) {
if(a[i] <= n) vis[a[i]] = 1;
while(vis[j]) ++j;
b[i] = j;
}
for(int i = n; i >= 1; i--) {
if(mp.find(a[i]) == mp.end()) nxt[i] = n + 1;
else nxt[i] = mp[a[i]];
mp[a[i]] = i;
}
}
void push_up(int o) {
sumv[o] = sumv[o << 1] + sumv[o << 1|1];
maxv[o] = max(maxv[o << 1], maxv[o << 1|1]);
}
void push_down(int o, int l, int r) {
if(lz[o] != -1) {
int mid = (l + r) >> 1;
lz[o << 1] = lz[o << 1|1] = lz[o];
sumv[o << 1] = 1ll * (mid - l + 1) * lz[o];
sumv[o << 1|1] = 1ll * (r - mid) * lz[o];
maxv[o << 1] = maxv[o << 1|1] = lz[o];
lz[o] = -1;
}
}
void build(int o, int l, int r) {
lz[o] = -1;
if(l == r) {
sumv[o] = maxv[o] = b[l];
return;
}
int mid = (l + r) >> 1;
build(o << 1, l, mid); build(o << 1|1, mid + 1, r);
push_up(o);
}
int query_l(int o, int l, int r, int L, int R, int v) {
if(l == r) return l;
int mid = (l + r) >> 1;
push_down(o, l, r);
int ok = -1;
if(maxv[o << 1] >= v && L <= mid) ok = query_l(o << 1, l, mid, L, R, v);
if(ok == -1 && maxv[o << 1|1] >= v && R > mid) ok = query_l(o << 1|1, mid + 1, r, L, R, v);
return ok;
}
void update(int o, int l, int r, int L, int R, int v) {
if(L <= l && r <= R) {
lz[o] = v;
sumv[o] = 1ll * (r - l + 1) * v;
maxv[o] = v;
return;
}
push_down(o, l, r);
int mid = (l + r) >> 1;
if(L <= mid) update(o << 1, l, mid, L, R, v);
if(R > mid) update(o << 1|1, mid + 1, r, L, R, v);
push_up(o);
}
ll query(int o, int l, int r, int L, int R) {
if(L <= l && r <= R) {
return sumv[o];
}
push_down(o, l, r);
int mid = (l + r) >> 1;
ll res = 0;
if(L <= mid) res += query(o << 1, l, mid, L, R);
if(R > mid) res += query(o << 1|1, mid + 1, r, L, R);
return res;
}
int main() {
while(cin >> n && n) {
for(int i = 1; i <= n; i++) cin >> a[i];
Getmex();
build(1, 1, n);
ll ans = query(1, 1, n, 1, n);
for(int i = 1; i < n; i++) {
int Next = nxt[i] - 1;
int L = query_l(1, 1, n, i + 1, Next, a[i]);
if(L != -1) update(1, 1, n, L, Next, a[i]);
ans += query(1, 1, n, i + 1, n);
}
cout << ans << '\n';
}
return 0;
}
HDU4747:Mex(线段树区间修改)的更多相关文章
- Codeforces Round #442 (Div. 2) E Danil and a Part-time Job (dfs序加上一个线段树区间修改查询)
题意: 给出一个具有N个点的树,现在给出两种操作: 1.get x,表示询问以x作为根的子树中,1的个数. 2.pow x,表示将以x作为根的子树全部翻转(0变1,1变0). 思路:dfs序加上一个线 ...
- 题解报告:hdu 1698 Just a Hook(线段树区间修改+lazy懒标记的运用)
Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for m ...
- poj 2528 线段树区间修改+离散化
Mayor's posters POJ 2528 传送门 线段树区间修改加离散化 #include <cstdio> #include <iostream> #include ...
- E - Just a Hook HDU - 1698 线段树区间修改区间和模版题
题意 给出一段初始化全为1的区间 后面可以一段一段更改成 1 或 2 或3 问最后整段区间的和是多少 思路:标准线段树区间和模版题 #include<cstdio> #include& ...
- HDU 4027 Can you answer these queries? (线段树区间修改查询)
描述 A lot of battleships of evil are arranged in a line before the battle. Our commander decides to u ...
- poj2528 Mayor's posters(线段树区间修改+特殊离散化)
Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral electio ...
- hiho_1078_线段树区间修改
题目 给定一组数,要求进行若干次操作,这些操作可以分为两种类型: (1) CMD 1 beg end value 将数组中下标在[beg, end] 区间内数字都变为value (2) CMD 2 b ...
- HDU-4747 Mex 线段树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意:求一个数列中,所有mex(L,R)的和. 注意到mex是单调不降的,那么首先预处理出mex ...
- [置顶] hdu4747 Mex 线段树
题意:给你一个序列,让你求出对于所有区间<i, j>的mex和,mex表示该区间没有出现过的最小的整数. 思路:从时限和点数就可以看出是线段树,并且我们可以枚举左端点i, 然后求出所有左端 ...
随机推荐
- TensorFlow基础篇
Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算.TensorFlow的运行机制属于“定义”和“运行”相分离.模型的构建只是相当于定义了一个图结构(代表一个计算任务),图中有 ...
- [E] Shiro 官方文档阅读笔记 The Reading Notes of Shiro's Offical Docs
官方文档: https://shiro.apache.org/reference.html https://shiro.apache.org/java-authentication-guide.htm ...
- 如何为python 2.7安装tensorflow?
“TensorFlow在Windows上支持Python 3.5.x和3.6.x.” 因此,您无法在Windows上使用Python 2.7的tensorflow 如果您被迫使用Python 2.7, ...
- Java 微信支付分对接记录 (先享后付)
微信支付分(先享后付)对接记录: 微信支付分对接步骤 填写开通支付分的申请表格 此步骤大概需要审核 1-3 个工作日; (模板-服务信息配置表-[先享后付免确认]-[商户名].xls) 填写商户信息 ...
- Spring Cloud灰度发布之Nepxion Discovery
<蓝绿部署.红黑部署.AB测试.灰度发布.金丝雀发布.滚动发布的概念与区别> 最近公司项目在做架构升级,升级为 Spring Cloud,我们希望能够做到服务的灰度发布,根据访问量逐渐切换 ...
- 初次用R的实际案例数据分析
这是一次教授布置的期末作业,也是书籍<商务数据分析与应用>的一个课后作业 目录 数据描述 数据预处理 描述性统计分析 模型分析(方差分析) 数据描述 非学位职业培训机构的178个学员的数据 ...
- Spring-Boot-操作-Redis,三种方案全解析!
在 Redis 出现之前,我们的缓存框架各种各样,有了 Redis ,缓存方案基本上都统一了,关于 Redis,松哥之前有一个系列教程,尚不了解 Redis 的小伙伴可以参考这个教程: Redis 教 ...
- react的标记渲染机制
// ReactUpdates.js - enqueueUpdate(component) function dirtyComponents.push(component); https://jue ...
- 关于wordpress4.8中的Twenty Seventeen主题的主题选项增加章节的实现
我这里的wordpress版本是4.8 默认的主题是 Twenty Seventeen 我想实现的事 主题选项的首页 多增加2个章节 默认是只有4个章节 我想在增加2个 到6个 看下实现后的效果 ...
- Macbook中VMWare的Centos7虚拟机配置静态IP并允许上网的配置方法
一.检查Macbook本身的配置 1.打开[系统偏好设置]-[网络]- 选中[Wi-Fi]项(如果您是WIFI上网请选择此项)- 点右侧[高级] 选择[TCP/IP]选项卡,记录好[子网掩码].[路由 ...