• [BZOJ4137][FJOI2015]火星商店问题


    luogu

    description

    有若干个(mbox{vector}),支持单点(mbox{push_back}),以及询问最近(d)(mbox{push_back})操作中在区间([l,r])内的数与(k)的异或最大值。
    所有数(le10^5)

    sol

    开一棵线段树,每个节点是一棵(mbox{Trie})树,这样就可以查异或最大值了。
    怎么处理时间的限制呢?在(mbox{Trie})树的每个节点维护一下这个节点的最新更新时间,查询的时候如果这个最新更新时间大于一个和(d)有关的限制就表示可以往这个子树走,否则就不行。

    然后这样子据说会(MLE)
    所以就把所有修改个询问都挂链挂到每个线段树的节点上,再离线线段树分治,这样空间复杂度就可以优化到(O(nlog n))

    code

    我不管反正我就是写在线做法。
    洛谷过了,然后(BZ)的数据本地测过了。别的我不管qwq。

    #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;
    }
    const int N = 1e5+5;
    int n,m,tim,ch[2][N*100],val[N*100],R[N],rt[N<<2],tot,ans;
    void mdf1(int &x,int p,int dep){
    	++tot;ch[0][tot]=ch[0][x];ch[1][tot]=ch[1][x];
    	val[tot]=val[x]+1;x=tot;if (!~dep) return;
    	mdf1(ch[(p>>dep)&1][x],p,dep-1);
    }
    int qry1(int x,int y,int p,int dep){
    	if (!~dep) return 0;int c=~(p>>dep)&1;
    	if (val[ch[c][x]]-val[ch[c][y]]) return qry1(ch[c][x],ch[c][y],p,dep-1)|(1<<dep);
    	c^=1;return qry1(ch[c][x],ch[c][y],p,dep-1);
    }
    void mdf2(int &x,int p,int dep,int t){
    	if (!x) x=++tot;val[x]=t;if (!~dep) return;
    	mdf2(ch[(p>>dep)&1][x],p,dep-1,t);
    }
    int qry2(int x,int p,int dep,int t){
    	if (!~dep) return 0;int c=~(p>>dep)&1;
    	if (val[ch[c][x]]>t) return qry2(ch[c][x],p,dep-1,t)|(1<<dep);
    	c^=1;return qry2(ch[c][x],p,dep-1,t);
    }
    void modify(int x,int l,int r,int p,int v,int t){
    	mdf2(rt[x],v,16,t);
    	if (l==r) return;int mid=l+r>>1;
    	if (p<=mid) modify(x<<1,l,mid,p,v,t);
    	else modify(x<<1|1,mid+1,r,p,v,t);
    }
    void query(int x,int l,int r,int ql,int qr,int v,int t){
    	if (l>=ql&&r<=qr) {ans=max(ans,qry2(rt[x],v,16,t));return;}
    	int mid=l+r>>1;
    	if (ql<=mid) query(x<<1,l,mid,ql,qr,v,t);
    	if (qr>mid) query(x<<1|1,mid+1,r,ql,qr,v,t);
    }
    int main(){
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) mdf1(R[i]=R[i-1],gi(),16);
    	for (int i=1;i<=m;++i)
    		if (gi()){
    			int l=gi(),r=gi(),v=gi(),d=gi();
    			ans=qry1(R[r],R[l-1],v,16);
    			query(1,1,n,l,r,v,tim-d);printf("%d
    ",ans);
    		}else{
    			int p=gi(),v=gi();
    			modify(1,1,n,p,v,++tim);
    		}
    	return 0;
    }
    
  • 相关阅读:
    java的一些基本概念──JDK 、j2se 、j2sdk...
    shell函数的调用执行
    ICE第三方包简介及安装&ICE安装(linux)
    http状态码
    Grep命令学习笔记(转)
    STL map用法详解
    ubuntu下安装subversion客户端
    linux下安装Tomcat及设置JSP环境
    ICE总结
    struts开发
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9385869.html
Copyright © 2020-2023  润新知