hdu 4747 Mex
来源:互联网 发布:驾校预约软件 编辑:程序博客网 时间:2024/06/06 18:48
题意:给你N个数,枚举所有的L和R,问由区间[L,R]之间的数构成的集合里,哪一个数字没有出现,如果有多个,找出最早的一个,设其为x,求所以x的和。
如果固定R,设R这个位置的值为Key[R],可以发现整个x数列是递减的,随着R的左移,可以从当前的R到前一个Key[R]出现位置之间的X,都不应该大于R,如果发现了这个性质,就是一个简单的成段更新了。
#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <map>using namespace std;typedef long long LL;#define LL(x) (x<<1)#define RR(x) (x<<1|1)#define MID(a,b) (a+((b-a)>>1))const int N=2e5+5;set<int> order;map<int,int> H;int a[N],pre[N],pos[N],valu[N];struct Segtree{ LL sum[N*4]; int lKey[N*4],rKey[N*4],delay[N*4]; void PushUp(int ind) { lKey[ind]=lKey[LL(ind)]; rKey[ind]=rKey[RR(ind)]; sum[ind]=sum[LL(ind)]+sum[RR(ind)]; } void fun(int valu,int lft,int rht,int ind) { lKey[ind]=rKey[ind]=delay[ind]=valu; sum[ind]=valu*(rht-lft+1); } void PushDown(int ind,int lft,int rht) { if(delay[ind]!=-1) { int mid=MID(lft,rht); fun(delay[ind],lft,mid,LL(ind)); fun(delay[ind],mid+1,rht,RR(ind)); delay[ind]=-1; } } void build(int lft,int rht,int ind) { sum[ind]=lKey[ind]=rKey[ind]=0; delay[ind]=-1; if(lft==rht) lKey[ind]=rKey[ind]=sum[ind]=valu[lft]; else { int mid=MID(lft,rht); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); PushUp(ind); } } void updata(int st,int ed,int valu,int lft,int rht,int ind) { if(st<=lft&&rht<=ed) fun(valu,lft,rht,ind); else { PushDown(ind,lft,rht); int mid=MID(lft,rht); if(st<=mid) updata(st,ed,valu,lft,mid,LL(ind)); if(ed> mid) updata(st,ed,valu,mid+1,rht,RR(ind)); PushUp(ind); } } int query(int st,int ed,int valu,int lft,int rht,int ind) { if(lft==rht) { if(lKey[ind]>=valu) return lft; return -1; } else { int mid=MID(lft,rht),pos=-1; PushDown(ind,lft,rht); if(ed<=mid) pos=query(st,ed,valu,lft,mid,LL(ind)); else if(st>mid) pos=query(st,ed,valu,mid+1,rht,RR(ind)); else { if(lKey[RR(ind)]>=valu) pos=query(st,ed,valu,mid+1,rht,RR(ind)); else pos=query(st,ed,valu,lft,mid,LL(ind)); } PushUp(ind); return pos; } } int getValu(int pos,int lft,int rht,int ind) { if(lft==rht) return lKey[ind]; else { int mid=MID(lft,rht),tmp=0; PushDown(ind,lft,rht); if(pos<=mid) tmp=getValu(pos,lft,mid,LL(ind)); else tmp=getValu(pos,mid+1,rht,RR(ind)); PushUp(ind); return tmp; } }}seg;int main(){ int n; while(scanf("%d",&n)!=EOF) { if(n==0) break; int sc=0; order.clear(); H.clear(); memset(pre,-1,sizeof(pre)); for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(H.find(a[i])==H.end()) { H.insert(make_pair(a[i],sc++)); } else { pre[i]=pos[ H[a[i]] ]; } pos[H[a[i]]]=i; } int tmp=0; for(int i=n-1;i>=0;i--) { order.insert(a[i]); while(order.find(tmp)!=order.end()) tmp++; valu[i]=tmp; } seg.build(0,n-1,1); LL ans=0; for(int i=n-1;i>=0;i--) { ans+=seg.sum[1]; int st=pre[i]+1,ed=i-1,pos=-1; if(st<=ed) pos=seg.query(st,ed,a[i],0,n-1,1); if(pos!=-1) seg.updata(st,pos,a[i],0,n-1,1); seg.updata(i,n-1,0,0,n-1,1); } printf("%I64d\n",ans); } return 0;}
- hdu 4747 Mex
- HDU 4747 Mex
- hdu-4747-Mex
- hdu 4747 Mex
- hdu 4747 Mex
- hdu 4747 Mex
- HDU 4747 Mex
- HDU 4747 Mex
- hdu 4747 Mex
- HDU 4747 Mex
- HDU-4747 Mex
- [HDU 4747 Mex] Mex函数 线段树
- hdu 4747 Mex (线段树)
- hdu 4747 Mex 线段树
- HDU 4747 Mex (线段树)
- HDU 4747 Mex 区间更新
- hdu 4747Mex【线段树】
- HDU 4747 Mex (线段树)
- 生产者-消费者生产模式 在医疗器械当中的使用
- [网页设计] 27款后台管理页面设计 DIV+CSS+JS
- linux ssh远程登录原理及中断原理
- poj-3254-Corn Fields-状态压缩DP
- Web基础:正则
- hdu 4747 Mex
- 数位dp cf 55d
- 抽象工厂
- UINavigationBar 背景设置
- java Enum的使用方法
- POJ:1659 Frogs' Neighborhood (Havel-Hakimi定理)
- C# 操作word常用方法
- At.js实现的输入框参数提示
- FreeBSD+openvpn之ports安装过程