【题目分析】

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

调了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;
}
}
}

  

SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树的更多相关文章

  1. GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树

    GSS7Can you answer these queries VII 给出一棵树,树的节点有权值,有两种操作: 1.询问节点x,y的路径上最大子段和,可以为空 2.把节点x,y的路径上所有节点的权 ...

  2. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  3. SPOJ QTREE Query on a tree ——树链剖分 线段树

    [题目分析] 垃圾vjudge又挂了. 树链剖分裸题. 垃圾spoj,交了好几次,基本没改动却过了. [代码](自带常数,是别人的2倍左右) #include <cstdio> #incl ...

  4. SPOJ GSS7 - Can you answer these queries VII

    板的不能再板,链剖+线段树或者是LCT随便维护. 感觉唯一要注意的是跳链的时候要对$x$向上跳和$y$向上跳的情况分开讨论,而不能直接$swap$,因为只有两段接触的端点才能相互合并,而且每一次向上跳 ...

  5. QTREE3 spoj 2798. Query on a tree again! 树链剖分+线段树

    Query on a tree again! 给出一棵树,树节点的颜色初始时为白色,有两种操作: 0.把节点x的颜色置反(黑变白,白变黑). 1.询问节点1到节点x的路径上第一个黑色节点的编号. 分析 ...

  6. SPOJ 375 (树链剖分+线段树)

    题意:一棵包含N 个结点的树,每条边都有一个权值,要求模拟两种操作:(1)改变某条边的权值,(2)询问U,V 之间的路径中权值最大的边. 思路:最近比赛总是看到有树链剖分的题目,就看了论文,做了这题, ...

  7. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  8. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  9. SP6779 GSS7 - Can you answer these queries VII

    纯数据结构题,没有思维难度.直接用线段树求最大子段和的方法完成树上路径的合并.注意链上合并顺序要符合序列的前后顺序. #include <cstdio> #include <cstr ...

随机推荐

  1. log4sql介绍

    log4sql介绍log4j环境中简单配置的情况下可收集执行的SQL语句和JDBC执行情况,如预编译的”?“显示成参数的实际值 下载log4sql.jar第一步:http://log4sql.sour ...

  2. LR中下载文件的脚本

    #include "web_api.h" Action(){ int iflen; //文件大小 long lfbody; //响应数据内容大小 web_url("xxx ...

  3. 推荐一个markdown格式转html格式的开源JavaScript库

    这个markdown格式转html格式的开源JavaScript库在github上的地址: https://github.com/millerblack/markdown-js 从markdown 格 ...

  4. URAL 1776 Anniversary Firework (概率,区间DP)

    坑,一开始以为,分成两半的时候去最大那个就行了, 实际上这样是不对的,因为有可能出现小的一半的时间比大的要长, 因为还和等待次数有关,且转移的时候需要用到次数更小的状态, 所以状态定义为二维,dp[i ...

  5. 关键字: on

    关键字: on 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成 ...

  6. HDU 6052 To my boyfriend(容斥+单调栈)

    题意:对于一个n*m的方格,每个格子中都包含一种颜色,求出任意一个矩形包含不同颜色的期望. 思路: 啊啊啊啊啊,补了两天,总算A了这道题了,简直石乐志,前面的容斥还比较好写,后面的那个>13那个 ...

  7. java并发编程:Executor、Executors、ExecutorService

    1.Executor和ExecutorService Executor:一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable comma ...

  8. 【整理】C#文件操作大全

    文件与文件夹操作主要用到以下几个类: 1.File类: 提供用于创建.复制.删除.移动和打开文件的静态方法,并协助创建 FileStream 对象. msdn:http://msdn.microsof ...

  9. java集合测试类等

    package demo.mytest; import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;import ja ...

  10. Sass基本数据类型和各类型的原生方法

    数据类型: 数字:1,2,3,11,10px (可以带单位) 字符串:"asd",'asd',asd (有引号和无引号都是字符串类型) 如 $name : zhang san ; ...