[主席树套堆 区间修改 标记永久化] BZOJ 3489 A simple rmq problem
来源:互联网 发布:拼装枪的软件 编辑:程序博客网 时间:2024/06/02 04:12
“因为是OJ上的题,就简单点好了。” Orz
看看贴吧吧:http://tieba.baidu.com/p/2947256742#47989538012l
题目大意:区间只出现过一次的最大的数
记一下next
从左到右 删了之前的标记 再从这个点到next-1都打标记 然后就可以查询了
按一个坐标离线做强制转在线么 用主席树好了 第一次打主席树区间修改 空间两个log 不过这个的前提是标记永久化 不然就是n2了
#include<cstdio>#include<cstdlib>#include<algorithm>#include<queue>using namespace std;typedef long long ll;inline char nc(){static char buf[100000],*p1=buf,*p2=buf;if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }return *p1++;}inline void read(int &x){char c=nc(),b=1;for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}const int N=100005;struct Heap{priority_queue<int> q,del;void maintain() { while (!del.empty() && !q.empty() && del.top()==q.top()) del.pop(),q.pop(); }bool empty() { return q.size()==del.size(); }int top() { if (empty()) return 0; maintain(); return q.top(); }void push(int x) { maintain(); q.push(x); }void erase(int x) { maintain(); del.push(x); }};int ncnt,rcnt;int root[N*120],ls[N*120],rs[N*120],maxv[N*120];Heap T[N*4];inline void add(int &y,int x,int pos,int l,int r,int L,int R,int v){y=++ncnt; int mid=(l+r)>>1;if (L<=l && r<=R){T[pos].push(v);maxv[y]=T[pos].top();ls[y]=ls[x]; rs[y]=rs[x];return;}maxv[y]=maxv[x];if (R<=mid)add(ls[y],ls[x],pos<<1,l,mid,L,R,v),rs[y]=rs[x];else if (L>mid)add(rs[y],rs[x],pos<<1|1,mid+1,r,L,R,v),ls[y]=ls[x];elseadd(ls[y],ls[x],pos<<1,l,mid,L,mid,v),add(rs[y],rs[x],pos<<1|1,mid+1,r,mid+1,R,v);}inline void del(int &y,int x,int pos,int l,int r,int L,int R,int v){y=++ncnt; int mid=(l+r)>>1;if (L<=l && r<=R){T[pos].erase(v);maxv[y]=T[pos].top();ls[y]=ls[x]; rs[y]=rs[x];return;}maxv[y]=maxv[x];if (R<=mid)del(ls[y],ls[x],pos<<1,l,mid,L,R,v),rs[y]=rs[x];else if (L>mid)del(rs[y],rs[x],pos<<1|1,mid+1,r,L,R,v),ls[y]=ls[x];elsedel(ls[y],ls[x],pos<<1,l,mid,L,mid,v),del(rs[y],rs[x],pos<<1|1,mid+1,r,mid+1,R,v);}inline int query(int x,int t,int l,int r){if (l==r) return maxv[x];int mid=(l+r)>>1;if (t<=mid)return max(maxv[x],query(ls[x],t,l,mid));elsereturn max(maxv[x],query(rs[x],t,mid+1,r));}int n,a[N];int nxt[N],last[N];int ed[N];int main(){int l,r,lastans,Q;freopen("t.in","r",stdin);freopen("t.out","w",stdout);read(n); read(Q);for (int i=1;i<=n;i++) read(a[i]);for (int i=1;i<=n;i++) last[i]=n+1;for (int i=n;i;i--) nxt[i]=last[a[i]],last[a[i]]=i;for (int i=1;i<=n;i++)if (last[i]!=n+1)rcnt++,add(root[rcnt],root[rcnt-1],1,1,n,last[i],nxt[last[i]]-1,i);ed[1]=root[rcnt];for (int i=1;i<=n;i++){rcnt++,del(root[rcnt],root[rcnt-1],1,1,n,i,nxt[i]-1,a[i]);if (nxt[i]!=n+1)rcnt++,add(root[rcnt],root[rcnt-1],1,1,n,nxt[i],nxt[nxt[i]]-1,a[i]);ed[i+1]=root[rcnt];}lastans=0;while (Q--){read(l); read(r);l=(l+lastans)%n+1; r=(r+lastans)%n+1; if (l>r) swap(l,r);lastans=query(ed[l],r,1,n);printf("%d\n",lastans);}return 0;}
0 0
- [主席树套堆 区间修改 标记永久化] BZOJ 3489 A simple rmq problem
- [BZOJ]3489 A simple rmq problem 主席树套树
- BZOJ 3489 A simple rmq problem
- 【31.94%】【BZOJ 3489】A simple rmq problem
- bzoj 3489: A simple rmq problem
- BZOJ 3489 A simple rmq problem
- BZOJ 3489: A simple rmq problem 树套树
- BZOJ 3489 A simple rmq problem 可持久化树套树
- bzoj 3489 A simple rmq problem 可持久化树套树
- bzoj 3489: A simple rmq problem (KD-tree)
- 3489: A simple rmq problem
- bzoj 3489: A simple rmq problem 可持久化线段树套可持久化线段树
- BZOJ 4505 K个串 主席树标记永久化
- 【BZOJ3489】A simple rmq problem
- BZOJ3489 A simple rmq problem
- bzoj3489: A simple rmq problem
- HYSBZ3489-A simple rmq problem
- [BZOJ3489]A simple rmq problem(KD-tree||主席树+KD-tree小结)
- 机器学习和计算机视觉相关的数学基础-收藏
- Struts2中使用Session的两种方法
- [疯狂Java]NIO:Channel的map映射
- H5中video标签
- [Java视频笔记]day24
- [主席树套堆 区间修改 标记永久化] BZOJ 3489 A simple rmq problem
- dateformat中日期格式化的正则对应
- iOS兼容HTML语句
- 使用sqlite3 创建数据库
- SPI总线 通俗易懂讲解
- 让Android studio支持java8
- coredump 相关
- iOS 使用GCD同步请求的小例子<1>
- Android中各种奇葩,难解的Json