Problem Sometimes Naive

题目大意

  给你一棵n个节点的树,有点权。

  要求支持两种操作:

    操作1:更改某个节点的权值。

    操作2:给定u,v, 求 Σw[i][j]   i , j 为任意两点且i到j的路径与u到v的路径相交。

解题分析

  容易发现对于一个询问,答案为总点权和的平方 减去 去掉u--v这条链后各个子树的点权和的平方的和。

  开两棵线段树,tag1记录点权和,tag2记录某点的所有轻链子树的点权和的平方的和。

  每次沿着重链往上走时,直接加上这条重链的所有点的tag2和,若有重儿子则直接用tag1计算。由于该条重链必定为其父亲的轻链,故为防止计算重复,还需减去该重链所有点的tag1平方和。

  最后爬到同一颗重链后,还需计算重链上方所有点的贡献。

参考程序

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define V 100008
#define E 200008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/
int n,m,tot;
int val[V];
int size[V],fa[V],w[V],top[V],rk[V],dep[V],son[V]; struct line{
int u,v,nt;
line(int u=,int v=,int nt=):u(u),v(v),nt(nt){}
}eg[E];
int lt[V],sum; void add(int u,int v){
eg[++sum]=line(u,v,lt[u]); lt[u]=sum;
} struct Segment_Tree{
LL sum[V<<];
void clear(){
clr(sum,);
}
void pushup(int rt){
sum[rt] = (sum[rt<<] + sum[rt<<|]) % mo;
}
void update(int x,int val,int l,int r,int rt){
if (l==r){
sum[rt] += val;
sum[rt] = sum[rt] % mo;
return;
}
int m=(l+r)>>;
if (x <= m) update(x,val,lson);
if (m < x) update(x,val,rson);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt){
if (L<=l && r<=R){
return sum[rt];
}
int m=(l+r)>>;
LL res=;
if (L <= m) res += query(L,R,lson);
if (m < R) res += query(L,R,rson);
res = res % mo;
return res;
} }Ts,Td;
void init(){
clr(lt,); sum=; tot=;
Ts.clear();
Td.clear();
}
void dfs_1(int u){
dep[u]=dep[fa[u]]+; size[u]=; son[u]=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]) continue;
fa[v]=u;
dfs_1(v);
if (size[v]>size[son[u]]) son[u]=v;
size[u]+=size[v];
}
} void dfs_2(int u,int tp){
top[u]=tp; w[u]=++tot; rk[tot]=u;;
if (son[u]) dfs_2(son[u],tp);
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (v==fa[u]||v==son[u]) continue;
dfs_2(v,v);
}
} int sqr(int x){return 1ll*x*x %mo;}
void update(int x,int v){
int u=top[x];
while (fa[u]){
LL sum=Ts.query(w[u],w[u]+size[u]-,,n,);
Td.update(w[fa[u]],(sqr(val[x]-v)-sum**(val[x]-v) % mo)%mo,,n,);
u=top[fa[u]];
}
Ts.update(w[x],v-val[x],,n,);
val[x]=v;
}
LL query(int x,int y){
LL res=;
while (top[x]!=top[y]){
if (dep[top[x]]<dep[top[y]]) swap(x,y);
res += Td.query(w[top[x]],w[x],,n,);
res = res % mo; if (son[x]){
LL sum=Ts.query(w[son[x]],w[son[x]]+size[son[x]]-,,n,);
res = res + sum*sum;
res = res % mo;
}
LL sum=Ts.query(w[top[x]],w[top[x]]+size[top[x]]-,,n,); res = res - sum*sum;
res = res % mo;
while (res<) res+=mo;
x=fa[top[x]];
}
if (dep[x]>dep[y]) swap(x,y);
res += Td.query(w[x],w[y],,n,);
res = res % mo;
if (son[y]){
LL sum=Ts.query(w[son[y]],w[son[y]]+size[son[y]]-,,n,);
res = res + sum*sum;
res = res % mo;
}
if (fa[x]){
LL sum=Ts.query(,n,,n,)-Ts.query(w[x],w[x]+size[x]-,,n,);
res = res + sum*sum;
res = res % mo;
}
return res;
} int main(){
while (~scanf("%d %d",&n,&m)){
init();
rep(i,,n) scanf("%d",&val[i]);
rep(i,,n){
int u,v;
scanf("%d %d",&u,&v);
add(u,v); add(v,u);
}
dfs_1();
dfs_2(,);
rep(i,,n){
int k=val[i];
val[i]=;
update(i,k);
}
while (m--){
int x,u,v;
scanf("%d %d %d",&x,&u,&v);
if (x==) update(u,v);
else {
LL sum=Ts.query(w[],w[]+size[]-,,n,);
sum = sum * sum;
sum = sum - query(u,v);
sum = sum % mo;
while (sum<) sum+=mo;
printf("%lld\n",sum);
}
}
}
}

  

HDU 5405 (树链剖分+线段树)的更多相关文章

  1. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  2. Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. 189. Rotate Array -- 将数组前一半移到后一半

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...

  2. div中的字符换行

    div中的字符换行 转载自:http://blog.sina.com.cn/s/blog_6a79bc480100tizi.html   1.强制不换行,同时以省略号结尾. <div style ...

  3. java.util 类 TreeSet<E>

    java.lang.Object≥ java.util.AbstractCollection<E> ≥ java.util.AbstractSet<E> ≥ java.util ...

  4. Java script基础

    Java script基础 Js的每个语句后面都要有分号. <script  type="text/java script">所有JS内容</script> ...

  5. Java JDK 动态代理使用及实现原理分析

    转载:http://blog.csdn.net/jiankunking   一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理 ...

  6. [转]网络时间的那些事及 ntpq 详解

    Gentoo(也许其他发行版也是?)中 "ntpq -p" 的 man page 只有简短的描述:“打印出该服务器已知的节点列表和它们的状态概要信息.” 我还没见到关于这个命令的说 ...

  7. FZU 2216 The Longest Straight 模拟

    题目链接:The Longest Straight 就是一个模拟就是这样,T_T然而当时恶心的敲了好久,敲完就WA了,竟然有这么简单的方法,真是感动哭了.......xintengziji...zhi ...

  8. 精通JS 笔记

    一,javascript数据类型:undefined,null,boolean,number,string,object 五种加一种复杂类型. 注意大小写,区分大不写函数:functiontypeof ...

  9. UIWebView获得内容的高-作出自适应高的UIWebView

    http://blog.csdn.net/matrixhero/article/details/8443972 - (void)webViewDidFinishLoad:(UIWebView *)we ...

  10. IT公司100题-16-层遍历二元树

    问题描述: 层遍历二叉树,同一层从左往右打印. 定义二元查找树的结点为: typedef struct BSTreeNode { int data; BSTreeNode *left; BSTreeN ...