[CSP-S模拟测试]:Equation(数学+树状数组)
题目描述
有一棵$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(数学+树状数组)的更多相关文章
- [CSP-S模拟测试]:柱状图(树状数组+二分+三分)
题目描述 $WTH$获得了一个柱状图,这个柱状图一共有$N$个柱子,最开始第$i$根柱子的高度为$x_i$,他现在要将这个柱状图排成一个屋顶的形状,屋顶的定义如下:$1.$屋顶存在一个最高的柱子,假设 ...
- [CSP-S模拟测试]:影魔(树状数组+线段树合并)
题目背景 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄.每一个灵魂,都有着自己 ...
- [CSP-S模拟测试]:统计(树状数组+乱搞)
题目传送门(内部题120) 输入格式 第一行,两个正整数$n,m$. 第二行,$n$个正整数$a_1,a_2,...,a_n$,保证$1\leqslant a_i\leqslant n$,可能存在相同 ...
- csp-s模拟测试56(10.2)Merchant「二分」·Equation「树状数组」
又死了......T1 Merchant 因为每个集合都可以写成一次函数的形式,所以假设是单调升的函数,那么随着t越大就越佳 而单调减的函数,随着t的增大结果越小,所以不是单调的??? 但是我们的单调 ...
- [CSP-S模拟测试]:天才绅士少女助手克里斯蒂娜(数学+树状数组)
题目描述 红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响. 选取显像管的任意一个平面,一开始平面内有个$n$电子,初始速度分别为$v_i$,定义飘升系数为$$\sum \li ...
- D 区间求和 [数学 树状数组]
D 区间求和 题意:求 \[ \sum_{k=1}^n \sum_{l=1}^{n-k+1} \sum_{r=l+k-1}^n 区间前k大值和 \] 比赛时因为被B卡了没有深入想这道题 结果B没做出来 ...
- 【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 ...
- 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 ...
- poj 2299 树状数组求逆序对数+离散化
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 54883 Accepted: 20184 ...
随机推荐
- Fiddler抓百度请求
fiddler是一个很好的抓包工具,默认是抓http请求的,对于pc上的https请求,会提示网页不安全,这时候需要在浏览器上安装证书. 一.网页不安全 1.用fiddler抓包时候,打开百度网页:h ...
- 剑指offer--day06
1.1 题目:调整数组顺序使奇数位语偶数前面:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的 ...
- kNN算法实例(约会对象喜好预测和手写识别)
import numpy as np import operator import random import os def file2matrix(filePath):#从文本中提取特征矩阵和标签 ...
- Oracle的substr函数简单用法(转)
转:http://www.cnblogs.com/nicholas_f/articles/1526063.html substr(字符串,截取开始位置,截取长度) //返回截取的字 substr('H ...
- IQueryable在LINQ中
IQueryable接口定义如下: // 摘要: // 提供对未指定数据类型的特定数据源的查询进行计算的功能. public interface IQueryable : IEnumerable { ...
- vscode怎么修改颜色主题里的某种颜色
我习惯用深色主题, 齿轮--->颜色主题 ---->monokai是我的菜. 比较精神,又不刺眼. 但是这个主题的注释的颜色太浅了. 几乎和背景重合. 注释很重要, 能体现和记录自己的代码 ...
- 【洛谷p1309】瑞士轮
因为太菜不会写P1310 表达式的值,就只能过来水两篇博客啦qwq 另外这个题我是开o2才过的(虽然是写了归并排序)(可能我太菜写的归并不是还可以“剪枝”吧qwq)哎,果真还是太菜啦qwq 所以准备写 ...
- 使用内核LED框架搭建驱动 ——led_classdev_register
#include <linux/init.h> // __init __exit #include <linux/module.h> // module_init module ...
- AtCoder Beginner Contest 133 B - Good Distance
地址:https://atcoder.jp/contests/abc133/tasks/abc133_b 核心问题:判断一个浮点数开方是否为整数 ; double ans1=sqrt(ans); if ...
- POJ-2528 Mayor's posters (离散化, 线段树)
题目传送门: POJ-2528 题意就是在一个高度固定的墙面上贴高度相同宽度不同的海报,问贴到最后还能看到几张?本质上是线段树区间更新问题,但是要注意的是题中所给数据范围庞大,直接搞肯定会搞出问题,所 ...