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. 条款8:别让异常逃离析构函数(prevent exception from leaving destructors)

    NOTE: 1.析构函数绝对不要吐出异常.如果一个被析构函数调用的函数可能抛出异常,析构函数应该扑捉任何异常,然后吞下他们(不传播)或结束程序. 2.如果客户需要对某个操作函数运行期间抛出的异常做出反 ...

  2. 南邮CTF--SQL注入题

    南邮CTF--SQL注入题 题目:GBK SQL injection 解析: 1.判断注入点:加入单引号发现被反斜杠转移掉了,换一个,看清题目,GBK,接下来利用宽字节进行注入 2.使用'%df' ' ...

  3. Django 再次学习笔记整理

    url 路由系统 urlpatterns = [ # path('admin/', admin.site.urls), path('index/', views.index), re_path('^e ...

  4. 【HIHOCODER 1478】 水陆距离(BFS)

    描述 给定一个N x M的01矩阵,其中1表示陆地,0表示水域.对于每一个位置,求出它距离最近的水域的距离是多少. 矩阵中每个位置与它上下左右相邻的格子距离为1. 输入 第一行包含两个整数,N和M. ...

  5. Insert or Merge

    7-13 Insert or Merge(25 分) According to Wikipedia: Insertion sort iterates, consuming one input elem ...

  6. js模式(一):单例模式

    function Universe(){ var instance; Universe = function (){ return instance; } Universe.prototype = t ...

  7. 图论trainning-part-1 D. Going in Cycle!!

    D. Going in Cycle!! Time Limit: 3000ms Memory Limit: 131072KB 64-bit integer IO format: %lld      Ja ...

  8. FZU-2147-2147 A-B Game,规律题。。

    Problem 2147 A-B Game Time Limit: 1000 mSec Memory Limit : 32768 KB  Problem Description Fat brother ...

  9. UVA 11090 判负圈问题

    题目链接http://vjudge.net/problem/viewProblem.action?id=34650 题目大意: 给定n个点m条边的加权有向图,求平均权值最小的回路.平均权值=路径权值之 ...

  10. CF788E:New task

    n个数字中,每个数有数字A和属性B,每次操作将某个点x的属性B改变为0或1,求满足这样要求的子序列的个数: 下标a<b<c<d<e,而Aa<=Ab=Ac=Ad>=A ...