Sometimes Naive

Problem Description
 
Rhason Cheung had a naive problem, and asked Teacher Mai for help. But Teacher Mai thought this problem was too simple, sometimes naive. So she ask you for help.

She has a tree with n vertices, numbered from 1 to n. The weight of i-th node is wi.

You need to support two kinds of operations: modification and query.

For a modification operation u,w, you need to change the weight of u-th node into w.

For a query operation u,v, you should output ∑ni=1∑nj=1f(i,j). If there is a vertex on the path from u to v and the path from i to j in the tree, f(i,j)=wiwj, otherwise f(i,j)=0. The number can be large, so print the number modulo 109+7

 
Input
There are multiple test cases.

For each test case, the first line contains two numbers n,m(1≤n,m≤105).

There are n numbers in the next line, the i-th means wi(0≤wi≤109).

Next n−1 lines contain two numbers each, ui and vi, that means that there is an edge between ui and vi.

The following are m lines. Each line indicates an operation, and the format is "1 u w"(modification) or "2 u v"(query)(0≤w≤109)

 
Output
For each test case, print the answer for each query operation.
 
Sample Input
6 5
1 2 3 4 5 6
1 2
1 3
2 4
2 5
4 6
2 3 5
1 5 6
2 2 3
1 1 7
2 2 4
 
Sample Output
341
348
612
 

题意:

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

  要求支持两种操作:

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

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

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 1e6+, M = 1e3+, mod = 1e9+, inf = 2e9; LL aa[N],bb[N],in[N],out[N];
int dep[N],head[N],t=,sz[N],fa[N],indexS,top[N],pos[N],son[N];
struct ss{int to,next;}e[N*];
int n;
void add(int u,int v)
{e[t].to = v;e[t].next = head[u];head[u] = t++;} void dfs(int u) {
int k = ;
sz[u] = ;
if(u!=)dep[u] = dep[fa[u]] + ;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(to == fa[u]) continue;
fa[to] = u;
dfs(to);
sz[u] += sz[to];
if(sz[to] > sz[k]) k = to;
}
if(k) son[u] = k;
}
void dfs(int u,int chain) {
int k = ;
pos[u] = ++indexS;
in[u] = indexS;
top[u] = chain;
if(son[u] > )
dfs(son[u],chain);
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(dep[to] > dep[u] && son[u] != to)
dfs(to,to);
}
out[u] = indexS;
} void update(int x,LL val,LL *sum) {
for(int i = x; i < N; i += i&(-i)) {
sum[i] += val;
sum[i] %= mod;
}
}
LL ask(int x,LL *sum) {
LL res = ;
for(int i = x; i; i-=i&(-i)) res += sum[i],res %= mod;
return res;
} LL allsum,C_tree[N],C_sqtree[N],a[N];
void update(int x,LL val) {
int u = top[x];
while(fa[u] > ) {
LL all = ask(out[u],C_tree) - ask(in[u]-,C_tree);
LL newall = (val - a[x])*(val - a[x])%mod + 1LL**all*(val-a[x])%mod;
update(in[fa[u]],newall%mod,C_sqtree);
u = top[fa[u]];
}
update(in[x],val-a[x],C_tree);
a[x] = val;
}
LL query(int x,int y) {
LL res = ,hav = ;
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
res += ask(in[x],C_sqtree) - ask(in[top[x]]-,C_sqtree);
res %= mod;
if(son[x]>) {
LL all = ask(out[son[x]],C_tree) - ask(in[son[x]]-,C_tree);
res += all*all;
res %= mod;
}
if(hav>) {
LL all = ask(out[hav],C_tree) - ask(in[hav]-,C_tree);
res -= all * all;
res %= mod;
}
hav = top[x];
x = fa[hav];
}
if(dep[x] < dep[y]) swap(x,y);
res += ask(in[x],C_sqtree) - ask(in[y]-,C_sqtree);
res %= mod;
if(fa[y] > ) {
LL all = ((ask(out[],C_tree) - ask(out[y],C_tree) + ask(in[y]-,C_tree))%mod+mod)%mod;
res += (all*all)%mod;
res %= mod;
}
if(son[x]>) {
LL all = ask(out[son[x]],C_tree) - ask(in[son[x]]-,C_tree);
res += all*all;
res %= mod;
}
if(hav>) {
LL all = ask(out[hav],C_tree) - ask(in[hav]-,C_tree);
res -= all * all;
res %= mod;
}
return res;
}
int Q;
void init() {
memset(head,,sizeof(head));
t = ;
indexS = ;
allsum = ;
memset(son,-,sizeof(son));
son[] = ;
memset(C_tree,,sizeof(C_tree));
memset(C_sqtree,,sizeof(C_sqtree));
}
int main() {
while(scanf("%d%d",&n,&Q)!=EOF) {
init();
for(int i = ; i <= n; ++i)
scanf("%I64d",&a[i]);
allsum = allsum*allsum%mod;
for(int i = ; i < n; ++i) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
fa[] = -;
dfs();
dfs(,);
for(int i = ; i <= n; ++i) {
LL uu = a[i];
a[i] = ;
update(i,uu);
}
while(Q--) {
int op,x;
LL y;
LL all = ask(out[],C_tree);
scanf("%d%d%I64d",&op,&x,&y);
if(op == ) {
update(x,y);
}
else
printf("%I64d\n",((all*all%mod - query(x,y)) % mod + mod)%mod);
}
}
return ;
}

HDU 5405 Sometimes Naive 树链剖分+bit*****的更多相关文章

  1. 2015多校第9场 HDU 5405 Sometimes Naive 树链剖分

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5405 题意: 给你一棵n个节点的树,有点权.        要求支持两种操作: 操作1:更改某个节点的 ...

  2. HDU 5029 Relief grain --树链剖分第一题

    题意:给一棵树,每次给两个节点间的所有节点发放第k种东西,问最后每个节点拿到的最多的东西是哪种. 解法:解决树的路径上的修改查询问题一般用到的是树链剖分+线段树,以前不会写,后来学了一下树链剖分,感觉 ...

  3. hdu 5029 Relief grain(树链剖分+线段树)

    题目链接:hdu 5029 Relief grain 题目大意:给定一棵树,然后每次操作在uv路径上为每一个节点加入一个数w,最后输出每一个节点个数最多的那个数. 解题思路:由于是在树的路径上做操作, ...

  4. HDU 5029 Relief grain 树链剖分打标记 线段树区间最大值

    Relief grain Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid= ...

  5. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  6. HDU 5044 Tree(树链剖分)

    HDU 5044 Tree field=problem&key=2014+ACM%2FICPC+Asia+Regional+Shanghai+Online&source=1&s ...

  7. hdu 5242——Game——————【树链剖分思想】

    Game Time Limit:1500MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status  ...

  8. hdu 5242 Game(树链剖分,贪心¥)

    Game Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  9. HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9123   Accepted: 2411 Description ...

随机推荐

  1. 条款16:成对使用new和delete时要采取相同形式

    NOTE: 1.如果你在new表达式中使用[],必须在相应的delete表达式中也使用[].如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[].

  2. Java:post请求

    文章来源:https://www.cnblogs.com/hello-tl/p/9140870.html 0.post请求返回json import java.io.BufferedInputStre ...

  3. Java:清空文件内容

    文章来源:https://www.cnblogs.com/hello-tl/p/9139432.html import java.io.*; public class FileBasicOperati ...

  4. 洛谷 P1156 垃圾陷阱 谈论剪枝,非满分

    这是一个91分的非dp代码(是我太弱) 剪枝八五个(实际上根本没那么多,主要是上课装逼,没想到他们dp水过去了),不过我的思路与dp不同: 1.层数到达i+1,return 这个必须有 2.当前剩余生 ...

  5. luogu2869 [USACO07DEC]美食的食草动物Gourmet Grazers

    先满足挑剔的 #include <algorithm> #include <iostream> #include <cstdlib> #include <cs ...

  6. 跟初学者学习IbatisNet第三篇

    这一章我们主要介绍一下IbatisNet里面的动态sql语句的运用,比如有时候我们想进行模糊查询,参数是动态加入的.或者要实现top n ,order by ,分页等功能的时候,我们就不得不用动态拼接 ...

  7. SQL Server 上关于同一张表里的三级联动

    或许这并不能叫做三级联动,三级联动是很容易实现的东西,有明确的层级关系,一般分开三张表存储.我在公司的项目里遇到这样一个问题,同一张表里面,有分公司,客户,项目3种关系,他们的层级关系是这样:分公司- ...

  8. AutoItLibrary之键盘操作(send)

    最近有人问到我键盘操作用什么库?用到库里面的哪个方法?我在这里总结一下,第一次写,有片面的地方还请指出,一块进步.1.首先,用到的库是AutoItLibrary,用到的方法是send:按F5可用看到 ...

  9. zoj 2727 List the Books

    List the Books Time Limit: 2 Seconds      Memory Limit: 65536 KB Jim is fond of reading books, and h ...

  10. Thread 1 cannot allocate new log 的处理办法

    ALTER SYSTEM ARCHIVE LOG Thread 1 cannot allocate new log, sequence 2594 Checkpoint not complete 这个实 ...