zoukankan      html  css  js  c++  java
  • SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树

    【题目分析】

        问题放到了树上,直接链剖+线段树搞一搞。

        调了300行+。

        (还是码力不够)

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    
    #include <map>
    #include <set>
    #include <queue>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 1000005
    #define eps 1e-8
    #define db double
    #define ll long long
    #define inf 0x3f3f3f3f
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("wa.txt","w",stdout);
        #endif
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    struct Node{
    	int lx,rx,mx,sum,lazy;
    	Node operator + (Node x)
    	{
    		Node ret;
    		ret.lx=max(lx,sum+x.lx);
    		ret.rx=max(x.sum+rx,x.rx);
    		ret.sum=sum+x.sum;
    		ret.mx=max(max(mx,x.mx),max(rx+x.lx,max(ret.lx,ret.rx)));
    		ret.lazy=-inf;
    		return ret;
    	}
    	void print()
    	{
    		printf("lx %d rx %d sum %d mx %d lazy %d
    ",lx,rx,sum,mx,lazy);
    	}
    	void init(){lx=rx=mx=sum=0;lazy=-inf;}
    }t[maxn];
    
    int n,a[maxn],b[maxn],q,L,R,tot,x,y,c;
    int h[maxn],to[maxn],ne[maxn],en=0;
    int fa[maxn],top[maxn],dep[maxn],siz[maxn],pos[maxn],son[maxn];
    
    void add(int a,int b)
    {
    	to[en]=b; ne[en]=h[a]; h[a]=en++;
    	to[en]=a; ne[en]=h[b]; h[b]=en++;
    }
    
    void build(int o,int l,int r)
    {
    	if (l==r)
    	{
    		t[o].lx=t[o].rx=t[o].mx=t[o].sum=a[l];
    		t[o].lazy=-inf;
    		return ;
    	}
    	int mid=l+r>>1;
    	build(o<<1,l,mid);
    	build(o<<1|1,mid+1,r);
    	t[o]=t[o<<1]+t[o<<1|1];
    	t[o].lazy=-inf;
    }
    
    void dfs1(int o)
    {
    	siz[o]=1;
    	for (int i=h[o];i>=0;i=ne[i])
    	{
    		if (to[i]!=fa[o])
    		{
    			fa[to[i]]=o;
    			dep[to[i]]=dep[o]+1;
    			dfs1(to[i]);
    			siz[o]+=siz[to[i]];
    			if (siz[to[i]]>siz[son[o]]) son[o]=to[i];
    		}
    	}
    }
    
    void dfs2(int o,int tp)
    {
    	top[o]=tp;
    	pos[o]=++tot;
    	a[tot]=b[o];
    	if (!son[o]) return ;
    	dfs2(son[o],tp);
    	for (int i=h[o];i>=0;i=ne[i])
    		if ((to[i]!=fa[o])&&(to[i]!=son[o]))
    			dfs2(to[i],to[i]);
    	return ;
    }
    
    Node q1[maxn],q2[maxn];
    
    void cov(int o,int c,int l,int r)
    {
    //	printf("Node %d %d %d %d
    ",o,c,l,r);
    	t[o].lx=c<0?c:(r-l+1)*c; //printf("%d %d
    ",c,(l-r+1)*c);
    	t[o].rx=c<0?c:(r-l+1)*c;
    	t[o].sum=(r-l+1)*c;
    	t[o].mx=c<0?c:(r-l+1)*c;
    //	printf("lx:%d rx:%d sum:%d mx:%d
    ",t[o].lx,t[o].rx,t[o].sum,t[o].mx);
    }
    
    void pushdown(int o,int l,int r)
    {
    	int mid=l+r>>1;
    	if (t[o].lazy!=-inf)
    	{
    //		printf("pushdown %d
    ",o);
    //		printf("in %d
    ",t[o].lazy);
    		t[o<<1].lazy=t[o<<1|1].lazy=t[o].lazy;
    		cov(o<<1,t[o].lazy,l,mid);
    		cov(o<<1|1,t[o].lazy,mid+1,r);
    	}
    	t[o].lazy=-inf;
    }
    
    Node Query(int o,int l,int r)
    {
    //	printf("q down
    ");
    	pushdown(o,l,r);
    //	printf("Query %d %d
    ",l,r); 
    	if (L<=l&&r<=R) return t[o];
    	int mid=l+r>>1;
    	if (L>mid) return Query(o<<1|1,mid+1,r);
    	else if (R<=mid) return Query(o<<1,l,mid);
    	else return Query(o<<1,l,mid)+Query(o<<1|1,mid+1,r);
    }
    
    
    void query()
    {
    	x=Getint(); y=Getint();
    //	printf("Query %d to %d
    ",x,y);
    	int p1=0,p2=0;
    	while (top[x]!=top[y])
    	{
    		if (dep[top[x]]>dep[top[y]])
    		{
    			L=pos[top[x]]; R=pos[x];
    			q1[++p1]=Query(1,1,n);
    //			printf("Query %d %d
    ",L,R);
    //			printf("at q1
    "); q1[p1].print();
    //			printf("x: %d to %d
    ",x,fa[top[x]]);
    			x=fa[top[x]];
    		}
    		else
    		{
    			L=pos[top[y]]; R=pos[y];
    //			printf("%d %d
    ",L,R);
    			q2[++p2]=Query(1,1,n);
    //			printf("Query %d %d
    ",L,R);
    //			printf("at q2
    "); q2[p2].print();
    //			printf("y: %d to %d
    ",y,fa[top[y]]);
    			y=fa[top[y]];
    		}
    	}
    	if (dep[x]>=dep[y])
    	{
    		L=pos[y]; R=pos[x];
    //		printf("%d %d
    ",L,R);
    		q1[++p1]=Query(1,1,n);
    //		printf("Query %d %d
    ",L,R);
    //		printf("at q1
    "); q1[p1].print();
    	}
    	else
    	{
    		L=pos[x]; R=pos[y];
    //		printf("%d %d
    ",L,R);
    		q2[++p2]=Query(1,1,n);
    //		printf("Query %d %d
    ",L,R);
    //		printf("at q2
    "); q2[p2].print();
    	}
    /*	Node ret1,ret2,ret; ret1.init();ret2.init();ret.init();
    	printf("q1begin
    ");
    	D(i,p1,1)
    	{
    		ret1.print();
    		ret1=ret1+q1[i];
    		q1[i].print();
    		ret1.print();
    	}
    	printf("q1 over
    ");
    	ret1.print();
    	printf("q2 begin
    ");
    	D(i,p2,1)
    	{
    		ret2.print();
    		ret2=ret2+q2[i];
    		q2[i].print();
    		ret2.print();
    	}
    	printf("q2 over
    ");
    //	ret1.init(); ret2.init();
    	ret1.print(); ret2.print();
    	swap(ret2.lx,ret2.rx);
    	ret=ret1+ret2; 
    	*/
    	Node ret,ret1,ret2; ret.init(); ret1.init(); ret2.init();
    	if (!p1)
    	{
    //		printf("only p2
    ");
    		ret=q2[1];
    		F(i,2,p2) ret=q2[i]+ret;
    	}
    	else if (!p2)
    	{
    //		printf("only p1
    ");
    		ret=q1[1];
    		F(i,2,p1) ret=q1[i]+ret;
    	}
    	else
    	{
    //		printf("both p1 and p2
    ");
    		ret1=q1[1];
    		F(i,2,p1) ret1=q1[i]+ret1;
    		ret2=q2[1];
    		F(i,2,p2) ret2=q2[i]+ret2;
    		swap(ret2.lx,ret2.rx);
    		ret=ret2+ret1;
    	}
    	printf("%d
    ",max(ret.mx,0));
    }
    
    
    void mod(int o,int l,int r)
    {
    //	printf("mod %d %d %d
    ",o,l,r);
    	pushdown(o,l,r);
    	int mid=l+r>>1;
    	if (L<=l&&r<=R)
    	{
    //		printf("tag on %d by %d %d to %d
    ",o,c,l,r);
    		t[o].lazy=c;
    		cov(o,c,l,r);
    		return ;
    	}
    	if (L<=mid) mod(o<<1,l,mid);
    	if (R>mid) mod(o<<1|1,mid+1,r);
    	t[o]=t[o<<1]+t[o<<1|1];
    }
    
    void Modify()
    {
    	x=Getint(); y=Getint(); c=Getint();
    	while (top[x]!=top[y])
    	{
    		if (dep[top[x]]<dep[top[y]]) swap(x,y);
    		L=pos[top[x]]; R=pos[x];
    //		printf("modify %d %d %d
    ",L,R,c);
    		mod(1,1,n); 
    		x=fa[top[x]];
    	}
    	if (dep[x]<dep[y]) swap(x,y);
    	L=pos[y]; R=pos[x]; 
    //	printf("modify %d %d %d
    ",L,R,c);
    	mod(1,1,n);
    }
    
    int main()
    {
    	memset(h,-1,sizeof h);
    	Finout(); n=Getint();
    	F(i,1,n) b[i]=Getint();
    	F(i,1,n-1) add(Getint(),Getint());
    	dfs1(1); dep[0]=-1;
    	dfs2(1,1);
    //	F(i,1,n) printf("Node %d : fa %d pos %d dep %d
    ",i,fa[i],pos[i],dep[i]);
    	build(1,1,n);
    	q=Getint();
    	F(i,1,q)
    	{
    		int opt=Getint();
    		switch(opt)
    		{
    			case 1: query(); break;
    			case 2: Modify(); break;
    		}
    	}
    }
    

      

  • 相关阅读:
    Redis简单案例(二) 网站最近的访问用户
    Redis简单案例(一) 网站搜索的热搜词
    Basic Tutorials of Redis(9) -First Edition RedisHelper
    Basic Tutorials of Redis(8) -Transaction
    Basic Tutorials of Redis(7) -Publish and Subscribe
    Basic Tutorials of Redis(6)
    Basic Tutorials of Redis(5)
    Basic Tutorials of Redis(4) -Set
    Basic Tutorials of Redis(3) -Hash
    Basic Tutorials of Redis(2)
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6360297.html
Copyright © 2011-2022 走看看