HDU-4747 二分+线段树
题意:给出长度为n的序列,问任两个区间的mex运算结果的总和。
解法:直接讲线段树做法:我们注意到mex(1,1),mex(1,2),mex(1,3)...mex(1,i)的结果是单调不减的,那么我们考虑先用线段树维护上诉结果,那么此时以1为左端点的区间mex和就求出来了,重点来了:我们考虑怎么从以1为左端点的区间结果过渡到以2为结点的区间结果呢?我们注意到其实只要以1为端点的区间去掉a[1]这个点的影响就可以得到以2为端点的区间结果,那么我们怎样去除a[1]这个点的影响呢?我们发现去掉a[1]之后会影响到的就是位置1到下一个a[1]出现位置的这一段区间!这一段区间的结果如果mex>a[1],那么因为a[1]的删除它的结果就会变成a[1]。且我们上面提到mex(1,1)到mex(1,n)的结果是单调不减的。那么我们就可以在线段树上二分来找一个mex>a[1]的点,区间修改即可。这样下去一边统计答案一边删除数修改影响,到最后就可以AC了。
这道题的线段树解法还是比较经典的做法的,对于一类问题:询问的是任两个区间的结果总和,而且发现我们能比较快速地通过删除最前面的数使得结果快速过渡到下一个区间的结果,那么我们可以考虑使用这种像前缀线段树(这个简称是蒟蒻瞎掰的qwq)的做法。
细节详见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=2e5+;
int n,a[N],f[N],nxt[N];
bool vis[N];
map<int,int> mp; LL sum[N<<],tag[N<<];
void pushup(int rt) {
sum[rt]=sum[rt<<]+sum[rt<<|];
}
void pushdown(int rt,int l1,int l2) {
if (tag[rt]==-) return;
sum[rt<<]=(LL)tag[rt]*l1; tag[rt<<]=tag[rt];
sum[rt<<|]=(LL)tag[rt]*l2; tag[rt<<|]=tag[rt];
tag[rt]=-;
}
void build(int rt,int l,int r) {
if (l==r) {
sum[rt]=f[l]; tag[rt]=-;
return;
}
sum[rt]=; tag[rt]=-;
int mid=l+r>>;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
pushup(rt);
}
void update(int rt,int l,int r,int ql,int qr,int v) {
if (ql<=l && r<=qr) {
sum[rt]=(LL)v*(r-l+); tag[rt]=v;
return;
}
int mid=l+r>>;
pushdown(rt,mid-l+,r-mid);
if (ql<=mid) update(rt<<,l,mid,ql,qr,v);
if (qr>mid) update(rt<<|,mid+,r,ql,qr,v);
pushup(rt);
}
LL query(int rt,int l,int r,int ql,int qr) {
if (ql<=l && r<=qr) return sum[rt];
int mid=l+r>>;
pushdown(rt,mid-l+,r-mid);
LL ret=;
if (ql<=mid) ret+=query(rt<<,l,mid,ql,qr);
if (qr>mid) ret+=query(rt<<|,mid+,r,ql,qr);
return ret;
} int main()
{
while (scanf("%d",&n) && n) {
for (int i=;i<=n;i++) scanf("%d",&a[i]);
for (int i=;i<=n;i++) vis[i]=;
for (int i=;i<=n;i++) {
if (a[i]<=n) vis[a[i]]=;
f[i]=f[i-];
while (vis[f[i]]) f[i]++;
}
mp.clear();
for (int i=n;i;i--) {
if (mp.count(a[i])) nxt[i]=mp[a[i]]; else nxt[i]=n+;
mp[a[i]]=i;
}
build(,,n);
LL ans=;
for (int i=;i<=n;i++) {
ans+=query(,,n,i,n);
int l=i,r=nxt[i]-,t=a[i];
while (l<r) {
int mid=l+r>>;
if (query(,,n,mid,mid)>t) r=mid; else l=mid+;
}
if (query(,,n,r,r)>t)
update(,,n,r,nxt[i]-,a[i]);
}
printf("%lld\n",ans);
}
return ;
}
HDU-4747 二分+线段树的更多相关文章
- hdu 4747 mex 线段树+思维
http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...
- hdu 4747【线段树-成段更新】.cpp
题意: 给出一个有n个数的数列,并定义mex(l, r)表示数列中第l个元素到第r个元素中第一个没有出现的最小非负整数. 求出这个数列中所有mex的值. 思路: 可以看出对于一个数列,mex(r, r ...
- HDU 6070 二分+线段树
Dirt Ratio Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Tot ...
- hdu 4747 Mex( 线段树? 不,区间处理就行(dp?))
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 4747 Mex ( 线段树好题 + 思路 )
参考:http://www.cnblogs.com/oyking/p/3323306.html 相当不错的思路,膜拜之~ 个人理解改日补充. #include <cstdio> #incl ...
- K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)
大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...
- hdu6070 Dirt Ratio 二分+线段树
/** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...
- HDU4614 Vases and Flowers 二分+线段树
分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
随机推荐
- html中代替空格、大于号、小于号等字符编码
数字表示法的不方便之处,在于必须知道每个字符的码点,很难记忆.为了能够快速输入,HTML 为一些特殊字符,规定了容易记忆的名字,允许通过名字来表示它们,这称为实体表示法(entity). 实体的写法是 ...
- mysql各种join连接查询
最近项目用到了几次sql join查询 来满足银行变态的需求:正好晚上自学时,看到了相关视频,所以记录下相关知识,下次再用时,根据如下图片,便可知道 怎么写sql; 注意点: 在join操作中的 on ...
- event(1)
event event(事件流)是 window对象的一个属性 在JS中事件有2种类型 一种是冒泡类型 一种是捕获类型 冒泡类型最先是在IE中出现,而捕获类型最先在标准的DOM中出现,不过最终IE得胜 ...
- 15.stop引发的数据不一致
/** * 数据不一致问题 * stop */ public class StopDemo { public static Student student = new Student(); publi ...
- leetcode-第14周双周赛-1274-矩形内船只的数目
题目描述: 自己的提交: # """ # This is Sea's API interface. # You should not implement it, or s ...
- 贾扬清谈大数据&AI发展的新挑战和新机遇
摘要:2019云栖大会大数据&AI专场,阿里巴巴高级研究员贾扬清为我们带来<大数据AI发展的新机遇和新挑战>的分享.本文主要从人工智能的概念开始讲起,谈及了深度学习的发展和模型训练 ...
- SSD接口详解,再也不会买错固态硬盘了
http://stor.51cto.com/art/201808/582349.htm 硬盘知识科普中,我们提到了SSD的发展史虽短,但是种类和协议比HDD不知道多到哪里去了.因此,本期小编就通过接口 ...
- Json中判断是JSONArray还是JSONObject
聪明的人总是能想到别人会遇到的问题,提前给出解决方案. List propList = new ArrayList(); //装载数据的list JSONArray array= JSONArray. ...
- eureka学习(一)
eureka是一个注册中心,与zookeeper不同的是,eureka是restful格式的调用,zk是rpc,还有就是zk保证一致和容错,eureka则是可用和容错. 使用时首先要加入依赖 < ...
- Redis缓存接入监控、运维平台CacheCloud
改造RedisConnectionFactory /** * 根据缓存策略的不同,RedisConnectionFactory不同 * 示例是单机模式. * * @return */@Beanpubl ...