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\n",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\n",o,c,l,r);
	t[o].lx=c<0?c:(r-l+1)*c; //printf("%d %d\n",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\n",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\n",o);
//		printf("in %d\n",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\n");
	pushdown(o,l,r);
//	printf("Query %d %d\n",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\n",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\n",L,R);
//			printf("at q1\n"); q1[p1].print();
//			printf("x: %d to %d\n",x,fa[top[x]]);
			x=fa[top[x]];
		}
		else
		{
			L=pos[top[y]]; R=pos[y];
//			printf("%d %d\n",L,R);
			q2[++p2]=Query(1,1,n);
//			printf("Query %d %d\n",L,R);
//			printf("at q2\n"); q2[p2].print();
//			printf("y: %d to %d\n",y,fa[top[y]]);
			y=fa[top[y]];
		}
	}
	if (dep[x]>=dep[y])
	{
		L=pos[y]; R=pos[x];
//		printf("%d %d\n",L,R);
		q1[++p1]=Query(1,1,n);
//		printf("Query %d %d\n",L,R);
//		printf("at q1\n"); q1[p1].print();
	}
	else
	{
		L=pos[x]; R=pos[y];
//		printf("%d %d\n",L,R);
		q2[++p2]=Query(1,1,n);
//		printf("Query %d %d\n",L,R);
//		printf("at q2\n"); q2[p2].print();
	}
/*	Node ret1,ret2,ret; ret1.init();ret2.init();ret.init();
	printf("q1begin\n");
	D(i,p1,1)
	{
		ret1.print();
		ret1=ret1+q1[i];
		q1[i].print();
		ret1.print();
	}
	printf("q1 over\n");
	ret1.print();
	printf("q2 begin\n");
	D(i,p2,1)
	{
		ret2.print();
		ret2=ret2+q2[i];
		q2[i].print();
		ret2.print();
	}
	printf("q2 over\n");
//	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\n");
		ret=q2[1];
		F(i,2,p2) ret=q2[i]+ret;
	}
	else if (!p2)
	{
//		printf("only p1\n");
		ret=q1[1];
		F(i,2,p1) ret=q1[i]+ret;
	}
	else
	{
//		printf("both p1 and p2\n");
		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\n",max(ret.mx,0));
}


void mod(int o,int l,int r)
{
//	printf("mod %d %d %d\n",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\n",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\n",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\n",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\n",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;
		}
	}
}

  

posted @ 2017-02-01 20:08  SfailSth  阅读(107)  评论(0编辑  收藏  举报