【题目分析】

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

调了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. ycsb模板介绍

    #对应的mongodb uri参数等mongodb.url=mongodb://127.0.0.1:27010/test_1 #对应的mongo数据库名称mongodb.database=test_1 ...

  2. shell框架

    #!/bin/bash#注释#注释#环境变量相关,如下PATH=/sbin:/bin:/usr/bin:/usr/sbin #引入库函数,如下,类似于c语言的#include "*.h&qu ...

  3. python打飞机pro版

    # -*- coding: utf-8 -*- import pygame from sys import exit import random pygame.init() screen = pyga ...

  4. 联想e431笔记本更改硬盘模式bios设置的详细教程

    用硬盘安装系统,就要进入bios,将硬盘改为第一启动项即可重装系统.不同品牌的电脑,它的bios设置方法也就不同.那么,联想e431笔记本要如何更改硬盘模式呢?今天U大侠小编就和大家分享联想e431笔 ...

  5. osx launchpad图标的删除

    安装了个parallels desktop之后,OSX中的launchpad中的图标多了不少,可是好多都不是我自己想要的,我们该怎么删除或者修改呢,下面介绍一些方法: ①直接操作Appications ...

  6. CAD交互绘制mcdbsolid对象(网页版)

    主要用到函数说明: _DMxDrawX::DrawSolid 绘McDbSolid对象.详细说明如下: 参数 说明 DOUBLE dX1 第一个点X DOUBLE dY1 第一个点Y DOUBLE d ...

  7. CAD交互绘制批注(网页版)

    js中实现代码说明: 动态拖放时的绘制事件: function DynWorldDrawComment( pCustomEntity, pWorldDraw, curPt) { // 得到绘制参数. ...

  8. css布局--两列布局,左侧固定,右侧自适应(其中左侧要可以拖动,右侧水平滚动条)

    (css布局所要实现的效果) 在前端面试中经常会被问到CSS布局,两列布局,左侧固定,右侧自适应.前几天去面试,遇到了这道题的升级版,要求左侧可拖动,右侧要有水平滚动条.拿到题目确实有些大脑短路,不知 ...

  9. 【meet in middle】poj1840Eqs

    震惊!map的常数居然如此之大 Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43 ...

  10. 【Java_基础】并发、并行、同步、异步、多线程的区别

    1. 并发:位于同一个处理器上的多个已开启未完成的线程,在任意一时刻系统调度只能让一个线程获得CPU资源运行,虽然这种调度机制有多种形式(大多数是以时间片轮巡为主).但无论如何,都是通过不断切换需要运 ...