zoukankan      html  css  js  c++  java
  • BZOJ2588: Spoj 10628. Count on a tree

    裸的树上主席树。一般的主席树每个节点相当于一个前缀和,树上主席树每个节点相当于到根的和,可持久化的时候以树上的父亲为上一个版本。

    注意最后一行行末不能输出换行,否则会PE。

    upd: 用可持久化trie重写了一遍,和主席树本质相同写法不同,变快了。

    #include<algorithm>
    #include<cstdio>
    #define lb lower_bound
    using namespace std;
    const int N=1e5+5;
    typedef struct node*ptr;
    struct node{
    	ptr i,j;int s;
    }e[N*17];
    ptr a=e,f[N];
    void ins(int j,ptr*o){
    	for(int i=16;~i;--i){
    		*++a=**o,*o=a;
    		if(j>>i&1)o=&(*o)->j;
    		else
    			++(*o)->s,o=&(*o)->i;
    	}
    }
    int ask(int k,ptr s,ptr t,ptr u,ptr v){
    	int j=0;
    	for(int i=16;~i;--i){
    		int l=s->s+t->s-u->s-v->s;
    		if(k<=l)s=s->i,t=t->i,u=u->i,v=v->i;
    		else
    			k-=l,j|=1<<i,s=s->j,t=t->j,u=u->j,v=v->j;
    	}
    	return j;
    }
    struct edge{
    	int v;edge*s;
    }z[N*2];
    edge*b=z,*h[N];
    void ins(int u,int v){
    	edge s={v,h[u]};
    	*(h[u]=b++)=s;
    }
    typedef int arr[N];
    arr w,p,d,r,y,c,g;
    void dfs1(int u){
    	f[u]=f[p[u]];
    	ins(w[u],f+u);
    	r[u]=1;
    	for(edge*i=h[u];i;i=i->s)
    		if(i->v!=p[u]){
    			d[i->v]=d[p[i->v]=u]+1;
    			dfs1(i->v);
    			r[u]+=r[i->v];
    			if(r[i->v]>r[c[u]])
    				c[u]=i->v;
    		}
    }
    int lca(int s,int t){
    	for(;y[s]!=y[t];s=p[y[s]])
    		if(d[y[s]]<d[y[t]])s^=t,t^=s,s^=t;
    	return d[s]<d[t]?s:t;
    }
    struct buf{
    	char z[1<<23],*s;
    	char e[9<<17],*p;
    	buf():s(z),p(e){
    		z[fread(z,1,sizeof z,stdin)]=0;
    	}
    	~buf(){fwrite(e,1,p-e,stdout);}
    	operator int(){
    		int x=0;
    		while(*s<48)++s;
    		while(*s>32)
    			x=x*10+*s++-48;
    		return x;
    	}
    	void out(int x){
    		static char z[12];
    		char*i=z;
    		if(!x)*p++=48;
    		else{
    			while(x){
    				int y=x/10;
    				*i++=x-y*10+48,x=y;
    			}
    			while(i!=z)*p++=*--i;
    		}
    	}
    }it;
    int main(){
    	*(*f=e)=(node){e,e};
    	int n=it,m=it;
    	for(int i=1;i<=n;++i)
    		g[i-1]=w[i]=it;
    	sort(g,g+n);
    	for(int i=1;i<=n;++i)
    		w[i]=lb(g,g+n,w[i])-g;
    	for(int i=2;i<=n;++i){
    		int s=it,t=it;
    		ins(s,t),ins(t,s);
    	}
    	dfs1(1);
    	for(int i=1;i<=n;++i)
    		if(c[p[i]]!=i)
    			for(int j=i;j;j=c[j])y[j]=i;
    	int l=0;
    	while(m--){
    		int s=it^l,t=it,u=lca(s,t);
    		it.out(l=g[ask(it,f[s],f[t],f[u],f[p[u]])]);
    		if(m)*it.p++=10;
    	}
    }
    
  • 相关阅读:
    jsp <img src="“> src 相对路径的问题
    记一次Intellij-IDEA配置JDK1.8,支持Lambda新特性
    centOS6.5 查看 启动 关闭防火墙
    java设计模式之--工厂方法模式
    BlockingQueue之---ArrayBlockingQueue
    两个线程,一个为123456,一个为ABCDEF、交替打印出1A2B3C...
    JUC之---超好用的阻塞锁
    JUC之---读写锁
    java设计模式之--代理模式
    java设计模式之--线程安全的单例模式
  • 原文地址:https://www.cnblogs.com/f321dd/p/5683211.html
Copyright © 2011-2022 走看看