当前位置:网站首页>HDU 4747 Mex「建议收藏」
HDU 4747 Mex「建议收藏」
2022-07-07 21:51:00 【全栈程序员站长】
大家好,又见面了,我是全栈君。
题意:
给出一段数字a 定义mex(l,r)表示a[l]…a[r]中最小的不连续的数字 求出全部mex(l,r)的和
思路:
首先能够想到由l開始到n的全部数字的mex值必定是递增的 那么就能够求出以1開始到n的全部数字的mex 从前到后扫一遍就可以 这时能够求出[1,r]全部区间的mex和 利用线段树就可以
接着考虑怎样求[2,r]、[3,r]…. 由[1,r]到[2,r]的转变无非是去掉第一个数字 那么去掉一个数字的影响是什么呢?
比方去掉一个2 那他最多影响到下一个2出现的地方 并且 他仅仅是把mex>2的地方改成了2 即从2处截断 又由于之前所说的递增关系 所以影响的区间也一定是连续的!
那么我们就能够每次删掉一个数字 利用线段树找出他影响的区间 并把这个区间覆盖为那个删掉的数字
最后每次求和就是答案
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef __int64 ll;
#define N 201000
#define L(x) (x<<1)
#define R(x) ((x<<1)|1)
struct node
{
int l,r,val,lazy;
ll sum;
}tree[N*4];
int a[N],mex[N],next[N];
int n,l,r;
map<int,int> mp;
ll ans;
void up(int i)
{
tree[i].val=max(tree[L(i)].val,tree[R(i)].val);
tree[i].sum=tree[L(i)].sum+tree[R(i)].sum;
}
void down(int i)
{
if(tree[i].lazy!=-1)
{
tree[L(i)].lazy=tree[i].lazy;
tree[L(i)].val=tree[i].lazy;
tree[L(i)].sum=(tree[L(i)].r-tree[L(i)].l+1)*tree[i].lazy;
tree[R(i)].lazy=tree[i].lazy;
tree[R(i)].val=tree[i].lazy;
tree[R(i)].sum=(tree[R(i)].r-tree[R(i)].l+1)*tree[i].lazy;
tree[i].lazy=-1;
}
}
void init(int l,int r,int i)
{
tree[i].l=l; tree[i].r=r; tree[i].lazy=-1;
if(l==r)
{
tree[i].val=mex[l];
tree[i].sum=mex[l];
return ;
}
int mid=(l+r)>>1;
init(l,mid,L(i));
init(mid+1,r,R(i));
up(i);
}
void update(int l,int r,int i,int k)
{
if(l==tree[i].l&&r==tree[i].r)
{
tree[i].sum=(tree[i].r-tree[i].l+1)*k;
tree[i].val=k;
tree[i].lazy=k;
return ;
}
down(i);
int mid=(tree[i].l+tree[i].r)>>1;
if(r<=mid) update(l,r,L(i),k);
else if(l>mid) update(l,r,R(i),k);
else
{
update(l,mid,L(i),k);
update(mid+1,r,R(i),k);
}
up(i);
}
void query(int i,int k)
{
if(tree[i].l==tree[i].r)
{
if(tree[i].val>k) l=tree[i].l;
else l=n+1;
return ;
}
down(i);
if(tree[L(i)].val>k) query(L(i),k);
else query(R(i),k);
up(i);
}
int main()
{
int i,j;
while(~scanf("%d",&n))
{
if(!n) break;
mp.clear(); // get mex
j=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mp[a[i]]=1;
while(mp[j]) j++;
mex[i]=j;
}
mp.clear(); // get next
for(i=1;i<=n;i++) mp[a[i]]=n+1;
for(i=n;i>=1;i--)
{
next[i]=mp[a[i]];
mp[a[i]]=i;
}
//for(i=1;i<=n;i++) printf("%d %d\n",mex[i],next[i]);
init(1,n,1);
for(i=1,ans=0;i<=n;i++)
{
ans+=tree[1].sum;
query(1,a[i]);
r=next[i];
//printf("%d %d\n",l,r);
if(l<r)
{
update(l,r-1,1,a[i]);
}
update(i,i,1,0);
}
printf("%I64d\n",ans);
}
return 0;
}
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/116215.html原文链接:https://javaforall.cn
边栏推荐
- Wechat forum exchange applet system graduation design completion (4) opening report
- leetcode-520. 检测大写字母-js
- FreeLink开源呼叫中心设计思想
- Statistical method for anomaly detection
- LDO穩壓芯片-內部框圖及選型參數
- ArcGIS:矢量要素相同字段属性融合的两种方法
- Brush question 5
- Mysql索引优化实战二
- Brush question 6
- Tree background data storage (using webmethod) [easy to understand]
猜你喜欢
七月第一周
Cloud native is devouring everything. How should developers deal with it?
海内外技术人们“看”音视频技术的未来
Matlab 信号处理【问答随笔·2】
Ros2 topic (03): the difference between ros1 and ros2 [01]
高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
USB(十五)2022-04-14
深入理解Mysql锁与事务隔离级别
When copying something from the USB flash disk, an error volume error is reported. Please run CHKDSK
LeeCode -- 6. Zigzag transformation
随机推荐
GEE(三):计算两个波段间的相关系数与相应的p值
【微服务|SCG】gateway整合sentinel
智慧社區和智慧城市之間有什麼异同
PCI-Express接口的PCB布线规则
Bit operation
Mitsubishi PLC SLmP (MC) protocol
Brush question 5
LDO穩壓芯片-內部框圖及選型參數
网格(Grid)
力扣解法汇总648-单词替换
为什么市场需要低代码?
Technology at home and abroad people "see" the future of audio and video technology
树后台数据存储(採用webmethod)[通俗易懂]
Network security sqlmap and DVWA explosion
U盘拷贝东西时,报错卷错误,请运行chkdsk
网络安全-永恒之蓝
系统架构设计师备考经验分享:论文出题方向
Wechat forum exchange applet system graduation design (5) assignment
解决:信息中插入avi格式的视频时,提示“unsupported video format”
网络安全-burpsuit