题目描述

有一棵$n$个点的以$1$为根的树,以及$n$个整数变量$x_i$。树上$i$的父亲是$f_i$,每条边$(i,f_i)$有一个权值$w_i$,表示一个方程$x_i+x_{f_i}=w_i$,这$n−1$个方程构成了一个方程组。
现在给出$q$个操作,有两种类型:
$\bullet 1\ u\ v\ s$,表示询问加上$x_u+x_v=s$这个方程后,整个方程组的解的情况。具体来说,如果方程有唯一解,输出此时$x_1$的值;如果有无限多个解,输出$inf$;如果无解,输出$none$。注意每个询问是独立的。
$\bullet 2\ u\ w$,表示将$w_u$修改为$w$。


输入格式

从文件$equation.in$中读入数据。
第一行两个整数$n,q$。
接下来$n−1$行,第$i$行有两个整数$f_{i+1}$和$w_{i+1}$。
接下来$q$行,每行表示一个操作,格式见问题描述。


输出格式

输出到文件$equation.out$中。
对于每个询问输出一行表示答案。


样例

样例输入:

2 7
1 4
1 1 2 5
1 1 2 4
1 1 1 3
1 2 2 6
2 2 3
1 2 2 10
1 2 2 -10

样例输出:

none
inf
none
1
-2
8


数据范围与提示

对于所有数据,有$1\leqslant n,q\leqslant 10^6,1\leqslant f_i\leqslant i−1,1\leqslant u,v\leqslant n,−10^3\leqslant w,w_i\leqslant 10^3,−10^9\leqslant s\leqslant 10^9$。
$\bullet Subtask1(3\%)$,$n\leqslant 10,q=0$。
$\bullet Subtask2(18\%)$,$n=2$。
$\bullet Subtask3(32\%)$,$n,q\leqslant 10^3$。
$\bullet Subtask4(33\%)$,$n,q\leqslant 10^5$。
$\bullet Subtask5(14\%)$,没有特殊的约束。


题解

首先,思考在没有修改的情况下如何快速求出$1$的解,其实无非就是分深度的奇偶,然后算边的前缀和罢了,比方说下图:

不妨设$4$为已知$x$,那么$3$就是$w_3-x$,$2$就是$w_2-w_3+x$,$1$就是$w_1-w_2+w_3-x$,发现什么规律了没有?

有点类似于多步容斥的奇加偶减。

那么考虑如何修改,我们如果要改一条边,那么将会影响到这条边所连两点中儿子的整个子树,显然不能暴力修改。

发现这个问题其实就是区间修改,单点查询;不妨树状数组?

利用树状数组维护$DFS$序即可。

这个题稍卡常……

听说线段树会$TLE$?

时间复杂度:$\Theta((n+q)\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;}e[1000001];
int head[1000001],cnt;
int n,q;
int f[1000001],w[1000001];
int sum[1000001],depth[1000001],l[1000001],r[1000001],tim;
int tr[4000001];
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
void pre_dfs(int x)
{
l[x]=++tim;
for(int i=head[x];i;i=e[i].nxt)
{
depth[e[i].to]=depth[x]+1;
sum[e[i].to]=w[e[i].to]-sum[x];
pre_dfs(e[i].to);
}
r[x]=tim;
}
int lowbit(int x){return x&-x;}
void change(int l,int r,int w)
{
for(int i=l;i<=n;i+=lowbit(i))tr[i]+=w;
for(int i=r+1;i<=n;i+=lowbit(i))tr[i]-=w;
}
int ask(int x)
{
int res=0;
for(int i=l[x];i;i-=lowbit(i))res+=tr[i];
return res*(depth[x]&1?1:-1);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=2;i<=n;i++)
{
scanf("%d%d",&f[i],&w[i]);
add(f[i],i,w[i]);
}
depth[1]=1;
pre_dfs(1);
while(q--)
{
int opt;
scanf("%d",&opt);
if(opt&1)
{
int u,v,s;
scanf("%d%d%d",&u,&v,&s);
int flagu=sum[u]+ask(u);
int flagv=sum[v]+ask(v);
if((depth[u]&1)&&(depth[v]&1))
{
long long res=1LL*s-flagu-flagv;
if(res&1)puts("none");
else printf("%lld\n",res>>1);
}
else if(!(depth[u]&1)&&!(depth[v]&1))
{
long long res=1LL*flagu+flagv-s;
if(res&1)puts("none");
else printf("%lld\n",res>>1);
}
else
{
if(flagu+flagv==s)puts("inf");
else puts("none");
}
}
else
{
int u,v;
scanf("%d%d",&u,&v);
int delta=v-w[u];
w[u]=v;
if(!(depth[u]&1))delta=-delta;
change(l[u],r[u],delta);
}
}
return 0;
}

rp++

[CSP-S模拟测试]:Equation(数学+树状数组)的更多相关文章

  1. [CSP-S模拟测试]:柱状图(树状数组+二分+三分)

    题目描述 $WTH$获得了一个柱状图,这个柱状图一共有$N$个柱子,最开始第$i$根柱子的高度为$x_i$,他现在要将这个柱状图排成一个屋顶的形状,屋顶的定义如下:$1.$屋顶存在一个最高的柱子,假设 ...

  2. [CSP-S模拟测试]:影魔(树状数组+线段树合并)

    题目背景 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...

  3. [CSP-S模拟测试]:统计(树状数组+乱搞)

    题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...

  4. csp-s模拟测试56(10.2)Merchant「二分」·Equation「树状数组」

    又死了......T1 Merchant 因为每个集合都可以写成一次函数的形式,所以假设是单调升的函数,那么随着t越大就越佳 而单调减的函数,随着t的增大结果越小,所以不是单调的??? 但是我们的单调 ...

  5. [CSP-S模拟测试]:天才绅士少女助手克里斯蒂娜(数学+树状数组)

    题目描述 红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响. 选取显像管的任意一个平面,一开始平面内有个$n$电子,初始速度分别为$v_i$,定义飘升系数为$$\sum \li ...

  6. D 区间求和 [数学 树状数组]

    D 区间求和 题意:求 \[ \sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和 \] 比赛时因为被B卡了没有深入想这道题 结果B没做出来 ...

  7. 【XSY2714】大佬的难题 数学 树状数组

    题目描述 给你三个排列\(A,B,C\),求 \[ \sum_{1\leq x,y\leq n}[a_x<a_y][b_x<b_y][c_x<c_y] \] \(n\leq 2\ti ...

  8. HDU 2492 Ping pong(数学+树状数组)(2008 Asia Regional Beijing)

    Description N(3<=N<=20000) ping pong players live along a west-east street(consider the street ...

  9. poj 2299 树状数组求逆序对数+离散化

    Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 54883   Accepted: 20184 ...

随机推荐

  1. 应用安全-CTF-格式串漏洞

    主要影响c库中print家族函数 - > printf,sprintf,fprintf等 利用: SIP请求URI中格式串

  2. 21次C++作业

    //第一题目 class A //A为基类 {public: void f1( ); int i; protected: void f2(); int j; private: int k; }; /* ...

  3. CDH平台搭建解决离线安装依赖包的方法

    背景介绍: 1CDH开发平台在搭建的过程中,会遇到各种各样的问题,其中的各种依赖就是一个很让人头痛的问题.如果安装脚本文件出现了这种问题,那么就可以把以下的这种方法加入shell中,但是不要用yum来 ...

  4. C/C++ 引入头文件时 #include<***.h> 与 #include"***.h" 区别

    两种情况区分: 1.#include <> 编译器只会去系统文件目录中查找,找不到就报错. 2.#include " "  编译器会先在用户目录中查找,再到编译器设定的 ...

  5. SpringBoot使用RestTemplate

    SpringBoot使用RestTempate SpringBoot使用RestTemplate摘要认证 SpringBoot使用RestTemplate基础认证 设置pom引用 <?xml v ...

  6. [19/05/20-星期一] CSS_css的盒子模型

    一.盒子模型 <!DOCTYPE html> <html> <!-- div 标签 块级标签 主要用来网页布局, 会将其中的子元素内容作为一个独立的整体存在 默认宽度是页 ...

  7. VBA中如何用environ$ 或 environ方法取得环境变量?

    用索引号取得环境变量Sub EnumSEVars() Dim strVar As String Dim i As Long strVar = Environ$(i) & Then Exit F ...

  8. 小白学Python(18)——pyecharts 关系图 Graph

    Graph-基本示例 import json import os from pyecharts import options as opts from pyecharts.charts import ...

  9. python 模块调用的几种方式

    在python里面又很多模块,或者引用第三方模块,python 模块调用的几种方式,下面详细解说 1,import 模块名 2,from 模块 import  模块里面的小功能 3,from  模块 ...

  10. linux下查看Apache的访问日志及ip

    linux下查看Apache的实时访问日志:tail -f  /etc/httpd/logs/access_log 查看有哪些ip访问过:cat access_log |awk '{print $1} ...