• BZOJ3489:A simple rmq problem


    浅谈(K-D) (Tree)https://www.cnblogs.com/AKMer/p/10387266.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=3489

    主席树套主席树写法:https://www.cnblogs.com/AKMer/p/10197640.html

    可以同主席树套主席树写法一样,用可持久化搞掉第一维(pre),然后对于(n)个点((id,nxt)),直接查询区间([l,r][r+1,n+1])内的最大值即为答案。

    时间复杂度:(O(nlogn+msqrt{n}))

    空间复杂度:(O(nlogn))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define bo11 p[u].mx[0]<x1||p[u].mn[0]>x2
    #define bo12 p[u].mx[1]<y1||p[u].mn[1]>y2
    #define bo21 x1<=p[u].mn[0]&&p[u].mx[0]<=x2
    #define bo22 y1<=p[u].mn[1]&&p[u].mx[1]<=y2
    #define bo31 x1<=p[u].c[0]&&p[u].c[0]<=x2
    #define bo32 y1<=p[u].c[1]&&p[u].c[1]<=y2
    
    const int maxn=1e5+5,inf=2e9;
    
    int pos[maxn],tmp[maxn];
    int n,m,pps,lstans,x1,x2,y1,y2;
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct data {
    	int v,pre,nxt,id;
    
    	bool operator<(const data &a)const {
    		return pre<a.pre;
    	}
    }a[maxn];
    
    struct kd_tree {
    	int tot,root[maxn];
    
    	struct point {
    		int ls,rs,mxv,val,d;
    		int c[2],mn[2],mx[2];
    
    		bool operator<(const point &a)const {
    			if(c[pps]==a.c[pps])return c[0]<a.c[0];
    			return c[pps]<a.c[pps];
    		}
    	}p[maxn*18];
    
    	int build(int l,int r,int d) {
    		int mid=(l+r)>>1,u=mid;pps=d;
    		nth_element(p+l,p+mid,p+r+1);
    		if(l<mid)p[u].ls=build(l,mid-1,d^1);
    		if(r>mid)p[u].rs=build(mid+1,r,d^1);
    		p[u].d=d;return u;
    	}
    
    	void update(int u) {
    		int ls=p[u].ls,rs=p[u].rs;
    		int mxv=max(p[ls].mxv,p[rs].mxv);
    		p[u].mxv=max(mxv,p[u].val);
    		for(int i=0;i<2;i++) {
    			int mn=min(p[ls].mn[i],p[rs].mn[i]);
    			p[u].mn[i]=min(p[u].mn[i],mn);
    			int mx=max(p[ls].mx[i],p[rs].mx[i]);
    			p[u].mx[i]=max(p[u].mx[i],mx);
    		}
    	}
    
    	void insert(int lst,int &u,int x,int y,int v) {
    		u=++tot,p[u]=p[lst];
    		if(p[u].c[0]==x&&p[u].c[1]==y) {
    			p[u].val=v;
    			p[u].mn[0]=p[u].mx[0]=x;
    			p[u].mn[1]=p[u].mx[1]=y;
    			update(u);return;
    		}
    		int O=p[u].d,num=O?y:x;
    		if((num<p[u].c[O])||(num==p[u].c[O]&&x<p[u].c[0]))
    			insert(p[lst].ls,p[u].ls,x,y,v);
    		else insert(p[lst].rs,p[u].rs,x,y,v);
    		update(u);
    	}
    
    	void prepare() {
    		p[0].mn[0]=p[0].mn[1]=inf;
    		p[0].mx[0]=p[0].mx[1]=-inf;
    		for(int i=1;i<=n;i++) {
    			p[i].mn[0]=p[i].mn[1]=inf;
    			p[i].mx[0]=p[i].mx[1]=-inf;
    			p[i].c[0]=a[i].id;
    			p[i].c[1]=a[i].nxt;
    			p[i].mxv=-inf;
    		}
    		root[0]=build(1,n,0);
    		for(int i=1;i<=n;i++) {
    			insert(root[i-1],root[i],a[i].id,a[i].nxt,a[i].v);
    		}
    	}
    
    	void find(int u) {
    		if(p[u].mxv<lstans)return;
    		if(bo11||bo12)return;
    		if(bo21&&bo22) {lstans=max(lstans,p[u].mxv);return;}
    		if(bo31&&bo32) lstans=max(lstans,p[u].val);
    		if(p[u].ls)find(p[u].ls);
    		if(p[u].rs)find(p[u].rs);
    	}
    }T;
    
    int main() {
    	T.tot=n=read(),m=read();
    	for(int i=1;i<=n;i++) {
    		a[i].v=read(),a[i].id=i;
    		a[i].pre=pos[a[i].v],pos[a[i].v]=i;
    	}
    	for(int i=1;i<=n;i++)pos[i]=n+1;
    	for(int i=n;i;i--)
    		a[i].nxt=pos[a[i].v],pos[a[i].v]=i;
    	sort(a+1,a+n+1);
    	for(int i=1;i<=n;i++)tmp[i]=a[i].pre;
    	T.prepare();
    	for(int i=1;i<=m;i++) {
    		int l=(read()+lstans)%n+1,r=(read()+lstans)%n+1;
    		if(r<l)swap(l,r);x1=l,x2=r,y1=r+1,y2=n+1;
    		int pos=lower_bound(tmp+1,tmp+n+1,l)-tmp-1;
    		lstans=-inf,T.find(T.root[pos]);
    		if(lstans==-inf)lstans=0;
    		printf("%d
    ",lstans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    MySQL 之 数据操作
    MySQL 之 库操作,表操作
    Python之协程
    IO模式和IO多路复用
    python之线程
    Python--多线程、多进程常用概念
    计算机组成原理
    python基础-守护进程、守护线程、守护非守护并行
    win7旗舰版 安装IIS中出现的问题
    sql 2008数据事务日志已满处理方法
  • 原文地址:https://www.cnblogs.com/AKMer/p/10409064.html
Copyright © 2020-2023  润新知