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. jquery表单验证使用插件formValidator

    JQuery表单验证使用插件formValidator 作者: 字体:[增加 减小] 类型:转载 时间:2012-11-10我要评论 jquery表单验证使用插件formValidator,可供有需求 ...

  2. ASP.NET Web API中的依赖注入

    什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...

  3. eclipse 安装git的插件和上传项目

    这里有个链接,已经很详细的写了过程  博客1以及博客2.其实遇到安装的问题,就是因为我用的eclipse版本比较老,但是eclipse里面又装了好多插件,不想在重新安装eclipse.还有一个很好的博 ...

  4. 137. Single Number II——问题是查找,本质是hash查找,只是记录的是32 bit中各个位出现次数而已

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  5. Mysql date_sub函数使用

    mysql中内置函数date_add和date_sub能对指定的时间进行增加或减少一个指定的时间间隔,语法如下: DATE_ADD(date,INTERVAL expr type) DATE_SUB( ...

  6. [转]Windows的窗口刷新机制

    1.Windows的窗口刷新管理 窗口句柄(HWND)都是由操作系统内核管理的,系统内部有一个z-order序列,记录着当前窗口从屏幕底部(假象的从屏幕到眼睛的方向),到屏幕最高层的一个窗口句柄的排序 ...

  7. 对于服务器的识别的条件,header之类的使用

    根据上一节的内容的衔接 一:urllib.request的使用 headers的一些属性 User-Agent : 有些服务器或 Proxy 会通过该值来判断是否是浏览器发出的请求Content-Ty ...

  8. 【未完成0.0】Noip2012提高组day2 解题报告

    第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...

  9. @ModelAttribute注解的作用

    @ModelAttribute注解的作用:1.放在方法上注解不带属性: 方法无返回值: 执行其他方法时,先执行该注解标记方法. 如果方法中有将一些属性放入model的操作,其他方法model中也会共享 ...

  10. Linux内核-模块编译和安装

    我安装Ubuntu的时候是没有安装源码的,在没有安装源码前 /usr/src/ 目录下是只有两个包含内核的头文件的文件夹的: 我的内核版本是: 所以接下来就是先安装内核源码: 执行后,/usr/src ...