zoukankan      html  css  js  c++  java
  • [BZOJ3489]A simple rmq problem

    bzoj

    题意

    一个长度为(n)的序列,(m)次询问,每次询问区间([l,r])中只出现了一次的最大的数是多少。如果没有满足条件的数则答案为(0)
    (nle10^5,mle2*10^5),强制在线。

    sol

    对每个位置记前一个和它相同的位置(pre_i)(如果没有则为(0)),后一个和它相同的位置(nxt_i)(如果没有则为(n+1))。
    那么一次询问就是查询所有满足(iin[l,r],pre_iin[0,l-1],nxt_iin[r+1,n+1])(a_i)最大值。
    三维数点?可持久化树套树?
    我选择(kd-tree)

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    #define ls t[o].ch[0]
    #define rs t[o].ch[1]
    #define cmin(a,b) (a>b?a=b:a)
    #define cmax(a,b) (a<b?a=b:a)
    const int N = 1e5+5;
    int n,m,col[N],pre[N],nxt[N],head[N],root,D,lim[2][3],ans;
    struct node{
    	int d[3],v;
    	bool operator < (const node &b) const
    		{return d[D]<b.d[D];}
    }a[N];
    struct kdtree{int d[3],Min[3],Max[3],ch[2],v,mx;}t[N];
    void mt(int x,int y)
    {
    	cmax(t[x].mx,t[y].mx);
    	for (int i=0;i<3;++i)
    		cmin(t[x].Min[i],t[y].Min[i]),cmax(t[x].Max[i],t[y].Max[i]);
    }
    int build(int l,int r,int d)
    {
    	D=d;int o=l+r>>1;
    	nth_element(a+l,a+o,a+r+1);
    	for (int i=0;i<3;++i)
    		t[o].d[i]=t[o].Min[i]=t[o].Max[i]=a[o].d[i];
    	t[o].v=t[o].mx=a[o].v;
    	if (l<o) ls=build(l,o-1,(d+1)%3),mt(o,ls);
    	if (o<r) rs=build(o+1,r,(d+1)%3),mt(o,rs);
    	return o;
    }
    bool whole(int o)
    {
    	for (int i=0;i<3;++i)
    		if (t[o].Min[i]<lim[0][i]||t[o].Max[i]>lim[1][i])
    			return false;
    	return true;
    }
    bool in(int o)
    {
    	for (int i=0;i<3;++i)
    		if (t[o].d[i]<lim[0][i]||t[o].d[i]>lim[1][i])
    			return false;
    	return true;
    }
    bool empty(int o)
    {
    	for (int i=0;i<3;++i)
    		if (t[o].Min[i]>lim[1][i]||t[o].Max[i]<lim[0][i])
    			return true;
    	return false;
    }
    void query(int o)
    {
    	if (t[o].mx<=ans) return;//这个要加不然会TLE
    	if (whole(o)) {cmax(ans,t[o].mx);return;}
    	if (empty(o)) return;
    	if (in(o)) cmax(ans,t[o].v);
    	if (ls) query(ls);if (rs) query(rs);
    }
    int main()
    {
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) pre[i]=head[col[i]=gi()],head[col[i]]=i;
    	for (int i=1;i<=n;++i) head[i]=n+1;
    	for (int i=n;i;--i) nxt[i]=head[col[i]],head[col[i]]=i;
    	for (int i=1;i<=n;++i)
    	{
    		a[i].d[0]=i;a[i].d[1]=pre[i];a[i].d[2]=nxt[i];
    		a[i].v=col[i];
    	}
    	root=build(1,n,0);
    	while (m--)
    	{
    		int l=(gi()+ans)%n+1,r=(gi()+ans)%n+1;
    		if (l>r) swap(l,r);
    		lim[0][0]=l;lim[1][0]=r;
    		lim[0][1]=0;lim[1][1]=l-1;
    		lim[0][2]=r+1;lim[1][2]=n+1;
    		ans=0;query(root);printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    后台查询出来的list结果 在后台查询字典表切换 某些字段的内容
    easyui字典js 切换 jsp页面显示的内容
    easyui获取table列表中所有数据组装成json格式发送到后台
    java日常工作错误总结
    easyui模板页面 不良调查
    配置简单的拦截器java中
    读取pdf中的内容
    springMVC生成pdf文件
    C++之友元函数和友元类
    ROS初级教程 cmake cmakelist.txt 的编写教程
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8945898.html
Copyright © 2011-2022 走看看