HDU 5405 (树链剖分+线段树)
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 (树链剖分+线段树)的更多相关文章
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- 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 ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
随机推荐
- Java 集合系列 01 总体框架
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- fill_parent和wrap_content的区别
在Android布局文件中定义视图垂直或水平大小: android:layout_width和android_layout_height的属性有fill_parent.wrap_content和mat ...
- JAVA-数据库连接【转】
SqlServer.Oracle.MySQL的连接,除了地址和驱动包不同,其他都一样的. 1 public String urlString="jdbc:sqlserver://localh ...
- springmvc 配置直接访问页面
<mvc:view-controller path="/" view-name="/home"/> 在mvc中配置,访问路径就可以了
- 好用的json-path
$.store.book[?(@.price < 10)].title Here is a complete overview and a side by side comparison of ...
- Java 面向对象编程——第一章 初识Java
第一章 初识Java 1. 什么是Java? Java是一种简单的.面向对象的.分布式的.解释的.安全的.可移植的.性能优异的多线程语言.它以其强安全性.平台无关性.硬件结构无关性.语言简 ...
- eclipse debug时老提示edit source lookup path解决方案
用myeclipse debug web应用的时候,总提示edit source lookup path,每次都得手动选择项目,费时费力.在网上终于找到了方法. 搬运:http://www.educi ...
- Thinking in java之正则表达式小例子
public static final String POEM= "Twas brilling, and the slithy toves\n" + "Did gyre ...
- cf 307
一开始我是不想打的 又因为307这个数字太特殊了 毕竟307 希望今天的考试不要挂掉 http://codeforces.com/contest/551/problem/A #include< ...
- UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...