• ! TJOI2018xor



    思考:

    1问:像线段树合并一样合并trie树

    2问:点分治或者直接暴力路径上trie树

    题解说可持久化01trie咋又去看题解了

    想想,像树链剖分一样,只不过把查询移到trie上

    时间复杂度(O(nlog^2))

    链查询的复杂度是高了些

    再来一个01trie表示到根的路径差分一下

    时间复杂度(O(nlog))

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    	return f==1?x:-x;
    }
    const int N=1e5+4;
    struct _01trie{
    	int ch[N<<5][2],tg[N<<5],tot;
    	inline void insert(int p,int pre,int x){
    		for(int i=30,c;i>=0;i--){
    			c=(x>>i)&1;
    			ch[p][c^1]=ch[pre][c^1];
    			if(!ch[p][c])ch[p][c]=++tot;
    			p=ch[p][c];pre=ch[pre][c];
    			tg[p]=tg[pre]+1;
    		}
    	}
    	inline int query(int pl,int pr,int x){
    		int ret=0;
    		for(int i=30,c;i>=0;i--){
    			c=(x>>i)&1;
    			if(tg[ch[pr][c^1]]-tg[ch[pl][c^1]]){
    				ret|=(1<<i);
    				pl=ch[pl][c^1];pr=ch[pr][c^1];
    			}
    			else{pl=ch[pl][c];pr=ch[pr][c];}
    		}
    		return ret;
    	}
    }t1,t2;
    int n,Q,tim,dep[N],st[N],ed[N],pos[N],a[N],fa[N][20];
    vector<int>e[N];
    void dfs(int x){
    	t1.insert(x,fa[x][0],a[x]);
    	st[x]=++tim;pos[tim]=x;
    	dep[x]=dep[fa[x][0]]+1;
    	for(int i=1;(1<<i)<=dep[x];i++)
    		fa[x][i]=fa[fa[x][i-1]][i-1];
    	for(auto v:e[x])
    		if(v!=fa[x][0]){
    			fa[v][0]=x;
    			dfs(v);
    		}
    	ed[x]=tim;
    }
    inline int getlca(int u,int v){
    	if(dep[u]<dep[v])u^=v^=u^=v;
    	for(int i=17;i>=0;i--)
    		if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
    	if(u==v)return u;
    	for(int i=17;i>=0;i--)
    		if(fa[u][i]!=fa[v][i]){
    			u=fa[u][i];v=fa[v][i];
    		}
    	return fa[u][0];
    }
    int main(){
    	t1.tot=t2.tot=n=read();Q=read();
    	for(int i=1;i<=n;i++)a[i]=read();
    	for(int i=1,u,v;i<n;i++){
    		u=read();v=read();
    		e[u].push_back(v);e[v].push_back(u);
    	}
    	dfs(1);
    	for(int i=1;i<=n;i++)t2.insert(i,i-1,a[pos[i]]);
    	while(Q--){
    		static int op,x,y,z,lca;
    		op=read();x=read();y=read();
    		if(op==1)cout<<t2.query(st[x]-1,ed[x],y)<<"
    ";
    		else{
    			lca=getlca(x,y);
    			z=read();
    			cout<<max(t1.query(lca,x,z),t1.query(fa[lca][0],y,z))<<"
    ";
    		}
    	}
    	return (0-0);
    }
    
  • 相关阅读:
    monkey事件简介
    Monkey简介
    Package与Activity简介
    adb 命令
    安卓模拟器简介
    iis重启的几种方法
    window下安装FTP服务器
    防止dedecms注入文件挂马的解决方法
    织梦漏洞可疑PHP文件/article文件夹
    织梦Dedecms系统可疑文件include/filter.inc.php扫描出漏洞,该如何解决?
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12624444.html
Copyright © 2020-2023  润新知