[JZOJ4680] 自然数 [HDU4747] Mex
来源:互联网 发布:下列属于软件特性 编辑:程序博客网 时间:2024/05/16 18:37
Description
Solution
50%
显然,超过
枚举区间左边界,右边界左边界开始向右扫,维护一个标记数组和答案指针,指针随着标记的更新而增大
100%
我们发现,
先用
我们可以从左往右删掉当前第一个数,计算剩余区间的影响和答案
就是说,从
删掉第一个数,造成的影响是一个连续的区间(自己YY),这区间内的
如果得出了区间的左边界和区间的右边界,就可以很简单的用线段树维护。
由于
右边界就是下一个序列中等于它的位置(它后面都不会造成影响),可以预处理
于是在
Code
#include<cstdio>#include<cstdlib>#include<cmath>#include<algorithm>#include<cstring>#include<iostream>#define fo(i,a,b) for(i=a;i<=b;i++)#define fod(i,a,b) for(i=a;i>=b;i--)#define N 200005struct node{ long long sm,mx; int ls,rs;}tr[5*N];using namespace std;int n,a[N],lt[N],b[N],nd;long long lazy[5*N];bool bz[N];long long ans; void down(int now,int l,int mid,int r){ int ls=tr[now].ls,rs=tr[now].rs; if (lazy[now]!=-1) { tr[ls].sm=(mid-l+1)*lazy[now]; tr[rs].sm=(r-mid)*lazy[now]; tr[ls].mx=tr[rs].mx=lazy[now]; lazy[ls]=lazy[rs]=lazy[now]; lazy[now]=-1; }} void build(int now,int l,int r){ if(l==r) return; int mid=(l+r)/2; tr[now].ls=++nd; build(nd,l,mid); tr[now].rs=++nd; build(nd,mid+1,r);}void change(int now,int l,int r,int x,int y,int v){ if (x>y) return; if (l==x&&r==y) { tr[now].sm=v*(r-l+1); tr[now].mx=v; lazy[now]=v; return; } int ls=tr[now].ls,rs=tr[now].rs,mid=(l+r)/2; down(now,l,mid,r); if(y<=mid) change(ls,l,mid,x,y,v); else if(x>mid) change(rs,mid+1,r,x,y,v); else { change(ls,l,mid,x,mid,v); change(rs,mid+1,r,mid+1,y,v); } tr[now].sm=tr[ls].sm+tr[rs].sm; tr[now].mx=max(tr[ls].mx,tr[rs].mx);}int find(int now,int l,int r,int x,int y){ if (l==x&&r==y) return tr[now].sm; int ls=tr[now].ls,rs=tr[now].rs,mid=(l+r)/2; long long s; down(now,l,mid,r); if (y<=mid) s=find(ls,l,mid,x,y); else if (x>mid) s=find(rs,mid+1,r,x,y); else s=find(ls,l,mid,x,mid)+find(rs,mid+1,r,mid+1,y); return s; } int query(int now,int l,int r,int v){ if (l==r) { if (tr[now].mx<=v) return l+2; return l; } int ls=tr[now].ls,rs=tr[now].rs,mid=(l+r)/2; down(now,l,mid,r); if (tr[ls].mx>v) return query(ls,l,mid,v); else return query(rs,mid+1,r,v);}int main(){ cin>>n; int i,j; nd=1; build(1,1,n); fo(i,1,n) { scanf("%d",&a[i]); if (a[i]>=n) a[i]=n; b[lt[a[i]]]=i; lt[a[i]]=i; } fo(i,1,n) if (b[i]==0) b[i]=n+1; int p=0; ans=0; memset(lazy,255,sizeof(lazy)); fo(j,1,n) { bz[a[j]]=1; while (bz[p]==1) p++; ans+=p; change(1,1,n,j,j,p); } fo(j,1,n-1) { int lp=query(1,1,n,a[j]),rp=b[j]; change(1,1,n,lp,rp-1,a[j]); ans+=find(1,1,n,j+1,n); } cout<<ans;}
0 0
- [JZOJ4680] 自然数 [HDU4747] Mex
- 【HDU4747】【JZOJ4680】自然数
- hdu4747 mex 线段树
- hdu4747——Mex
- hdu4747 Mex (线段树 好题)
- hdu4747 Mex 线段树 (2013网络赛)
- HDU4747 2013 ACM/ICPC Asia Regional Hangzhou Online Mex(线段树)
- mex
- Mex
- mex
- mex
- 自然数
- hdu4747 线段树
- hdu4747(线段树区间更新)
- MEX文件
- 关于MEX
- Matlab MEX
- E - Mex
- TextView省略&相关处理
- 关联规则算法(The Apriori algorithm)详解
- rsync同步
- 等价、偏序和全序
- QT常用知识
- [JZOJ4680] 自然数 [HDU4747] Mex
- 抽象工厂模式
- C#中的枚举类型(enum type)
- python pygame实战《飞船大战外星人》
- 【Sublime】Mac下Sublime代码自动换行
- npm常用命令
- 动态规划——01背包问题
- Objective-C Runtime 运行时
- Gson 反序列化