2018ICPC网络赛(焦作站)E题题解
一、题目链接
二、题意
给定一棵树,有四种操作:
$1\ u\ v\ x$:把节点$u$到$v$路径上的所有点的权值乘以$x$;
$2\ u\ v\ x$:把节点$u$到$v$路径上的所有点的权值加上$x$;
$3\ u\ v$:把节点$u$到$v$路径上的所有点的权值取反(~操作);
$4\ u\ v$:查询节点$u$到$v$路径上的所有点的权值和;
所有操作都需要$mod\ 2^{64}$。
三、思路
操作1、2和4是很裸的树链剖分。关键是操作3。这里有个小技巧:对任意一个数字$x$取反,都等于$-(x+1)$。对于此题的$unsigned\ long\ long$类型,同样适用($-1$就是$1111\cdots1111_{(2)}=2^{64}-1$)。明白这个以后,取反操作可以变成加法和乘法。
然后要注意的是,线段树的区间加和区间乘的顺序问题,这里也有个技巧:如果区间$[l,r]$之前的和是$sum$,这个区间先加了一个$x$,再乘了一个$y$,那么可以变成$sum*y+x*y$。即让这个区间先乘一个$y$,再加上$x*y$。这样就可以保证以先乘后加的顺序不出问题了。
然后这题就愉快地AC了。
结论:对任意一个数$x$取反,无论这个数的类型是什么($int,unsigned\ int,long\ long,unsigned\ long\ long$都可以),都等于$-(x+1)$。
四、代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
typedef unsigned long long ULL;
struct edge {
int to, next;
edge(, ): to(to), next(next) {}
} es[MAXN * ];
int head[MAXN], ecnt;
int f[MAXN], deep[MAXN], siz[MAXN], zson[MAXN], top[MAXN], o2n[MAXN], dfscnt;
int n, q;
ULL a[MAXN];
namespace st {
struct node {
ULL sum, slazy, plazy;
node(ULL a1 = , ULL a2 = , ULL a3 = ): sum(a1), slazy(a2), plazy(a3) {}
} ns[MAXN * ];
void init() {
, t = * n + ; i < t; ++i)ns[i] = node(, , );
}
void pushdown(int rt, int l, int r) {
, rch = rt << | , mid = (l + r) >> ;
|| ns[rt].plazy != ) {
ns[lch].sum = ns[lch].sum * ns[rt].plazy + (mid - l + ) * ns[rt].slazy;
ns[rch].sum = ns[rch].sum * ns[rt].plazy + (r - mid) * ns[rt].slazy;
ns[lch].plazy *= ns[rt].plazy;
ns[rch].plazy *= ns[rt].plazy;
ns[lch].slazy = ns[lch].slazy * ns[rt].plazy + ns[rt].slazy;
ns[rch].slazy = ns[rch].slazy * ns[rt].plazy + ns[rt].slazy;
ns[rt].plazy = , ns[rt].slazy = ;
}
}
, , int r = n) {
if(l > ur || r < ul)return;
if(l >= ul && r <= ur) {
)ns[rt].sum += x * ULL(r - l + ), ns[rt].slazy += x;
else ns[rt].sum *= x, ns[rt].plazy *= x, ns[rt].slazy *= x;
return;
}
pushdown(rt, l, r);
;
, l, mid);
| , mid + , r);
ns[rt].sum = ns[rt << ].sum + ns[rt << | ].sum;
}
ULL query(, , int r = n) {
if(l > qr || r < ql)return 0LL;
if(l >= ql && r <= qr)return ns[rt].sum;
pushdown(rt, l, r);
;
ULL res = ;
, l, mid);
| , mid + , r);
return res;
}
};
void add(int from, int to) {
es[++ecnt] = edge(to, head[from]), head[from] = ecnt;
}
void init() {
memset(head, , ]) * (n + ));
ecnt = ;
memset(zson, , ]) * (n + ));
dfscnt = ;
st::init();
}
void dfs1(int root, int par) {
deep[root] = deep[par] + , f[root] = par, siz[root] = ;
;
for(int i = head[root]; i; i = es[i].next) {
int to = es[i].to;
if(to != par) {
dfs1(to, root);
siz[root] += siz[to];
if(ms < siz[to]) {
ms = siz[to], zson[root] = to;
}
}
}
}
void dfs2(int root, int par, int tp) {
top[root] = tp, o2n[root] = ++dfscnt;
st::update(dfscnt, dfscnt, a[root], );
if(!zson[root])return;
dfs2(zson[root], root, tp);
for(int i = head[root]; i; i = es[i].next) {
int to = es[i].to;
if(to != par && to != zson[root]) {
dfs2(to, root, to);
}
}
}
void update(int u, int v, ULL x, int type) {
int tu = top[u], tv = top[v];
while(tu != tv) {
if(deep[tu] >= deep[tv]) {
st::update(o2n[tu], o2n[u], x, type);
u = f[tu], tu = top[u];
}
else {
st::update(o2n[tv], o2n[v], x, type);
v = f[tv], tv = top[v];
}
}
if(o2n[u] <= o2n[v])st::update(o2n[u], o2n[v], x, type);
else st::update(o2n[v], o2n[u], x, type);
}
ULL query(int u, int v) {
int tu = top[u], tv = top[v];
ULL res = ;
while(tu != tv) {
if(deep[tu] >= deep[tv]) {
res += st::query(o2n[tu], o2n[u]);
u = f[tu], tu = top[u];
}
else {
res += st::query(o2n[tv], o2n[v]);
v = f[tv], tv = top[v];
}
}
if(o2n[u] <= o2n[v])res += st::query(o2n[u], o2n[v]);
else res += st::query(o2n[v], o2n[u]);
return res;
}
int main() {
// freopen("e.in","r",stdin);
int fa, op, u, v;
ULL x;
while(~scanf("%d", &n)) {
init();
; i <= n; ++i) {
scanf("%d", &fa);
add(fa, i), add(i, fa);
}
dfs1(, );
dfs2(, , );
scanf("%d", &q);
while(q--) {
scanf("%d", &op);
) {
scanf("%d%d%llu", &u, &v, &x);
update(u, v, x, );
}
) {
scanf("%d%d%llu", &u, &v, &x);
update(u, v, x, );
}
) {
scanf("%d%d", &u, &v);
update(u, v, , );
update(u, v, -, );
}
else {
scanf("%d%d", &u, &v);
ULL res = query(u, v);
printf("%llu\n", res);
}
}
}
;
}
2018ICPC网络赛(焦作站)E题题解的更多相关文章
- 2018ICPC网络赛(焦作站)K题题解
一.题目链接 https://nanti.jisuanke.com/t/31720 二.题意 给$N$种船只,第$i$种船的载重量是$V_i$,数量是$2^{C_i}-1$.接下来有$Q$次询问,每次 ...
- 2018ICPC网络赛(徐州站)A题题解
一.题目链接 https://nanti.jisuanke.com/t/31453 二.题意 给定$N$个位置,$2^k$种颜色,让你去涂色,条件是相邻的两种颜色类型异或值的二进制表示不全为$1$(以 ...
- 2013 ACM-ICPC亚洲区域赛南京站C题 题解 轮廓线DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4804 题目大意 给你一个 \(n \times m\) 的矩形区域.你需要用 \(1 \times 1 ...
- 2019CCPC网络预选赛 八道签到题题解
目录 2019中国大学生程序设计竞赛(CCPC) - 网络选拔赛 6702 & 6703 array 6704 K-th occurrence 6705 path 6706 huntian o ...
- HDU 4730 We Love MOE Girls (2013成都网络赛,签到水题)
We Love MOE Girls Time Limit: 1000/500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- SCNU省选校赛第二场B题题解
今晚的校赛又告一段落啦,终于"开斋"了! AC了两题,还算是满意的,英语还是硬伤. 来看题目吧! B. Array time limit per test 2 seconds me ...
- Building Fire Stations 39届亚洲赛牡丹江站B题
题意: 给你一棵树,让你再里面选取两个点作为**点,然后所有点的权值是到这两个点中最近的那个的距离,最后问距离中最长的最短是多少,输出距离还有那两个点(spj特判). 思路: 现场 ...
- hdu 5038 (2014北京网络赛G 排序水题)
题意:有n个数字,带入10000 - (100 - ai) ^ 2公式得到n个数,输出n个数中频率最大的数,如果有并列就按值从小到大都输出输出,如果频率相同的数字是全部的n个数,就输出Bad....题 ...
- 2018ACM-ICPC亚洲区域赛南京站I题Magic Potion(网络流)
http://codeforces.com/gym/101981/attachments 题意:有n个英雄,m个敌人,k瓶药剂,给出每个英雄可以消灭的敌人的编号.每个英雄只能消灭一个敌人,但每个英雄只 ...
随机推荐
- js之表单记忆功能
在项目中,我们难免会遇到希望相同用户操作本次打开页面时可以展现或者自动记录上次登录系统点击过的的复选框,单选按钮等操作的状态,也就是表单记忆功能,这时,一个很重要的技术便派上了用场,即cookie. ...
- python3:定时执行自动化测试脚本
转载请注明出处:https://www.cnblogs.com/shapeL/p/9172990.html 1.windows任务计划定时执行脚本 (1)创建 .bat 文件,执行脚本的命令(inte ...
- iOS 序列化和反序列化
摘自:http://hi.baidu.com/popln/blog/item/c3dd9302bb37e994d43f7ccb.html 开篇 1到底这个序列化有啥作用? 面向对象的程序在运行的时候会 ...
- 学会从后往前遍历,例 [LeetCode] Pascal's Triangle II,剑指Offer 题4
当我们需要改变数组的值时,如果从前往后遍历,有时会带来很多麻烦,比如需要插入值,导致数组平移,或者新的值覆盖了旧有的值,但旧有的值依然需要被使用.这种情况下,有时仅仅改变一下数组的遍历方向,就会避免这 ...
- .Net Core:部署应用
实战Asp.Net Core:部署应用 1.前言 某一刻,你已经把 .Net Core 的程序写好了.接下来,还可以做什么呢?那就是部署了. 作为一名开发工程师,如果不会部署自己开发的应用,那么这 ...
- (2)socket的基础使用(基于TCP协议)
socket()模块函数用法 基于TCP协议的套接字程序 netstart -an | findstr 8080 #查看所有TCP和UDP协议的状态,用findstr进行过滤监听8080端口 服务端套 ...
- ZH奶酪:Python 中缀表达式转换后缀表达式
实现一个可以处理加减乘数运算的中缀表达式转换后缀表达式的程序: 一个输入中缀表达式inOrder 一个输出池pool 一个缓存栈stack 从前至后逐字读取inOrder 首先看一下不包含括号的: ( ...
- TensorFlow笔记-05-反向传播,搭建神经网络的八股
TensorFlow笔记-05-反向传播,搭建神经网络的八股 反向传播 反向传播: 训练模型参数,在所有参数上用梯度下降,使用神经网络模型在训练数据上的损失函数最小 损失函数:(loss) 计算得到的 ...
- FastAdmin 开发环境详细设置
一图胜千言 FastAdmin开发环境 Windows 网页安装 鼠标点点就可以了,不用说明. 命令行安装 环境准备 装有 Windows 7 的PC .(这是一句废话,不用理这句.) 服务器软件 A ...
- Socket-Vs-WebSocket-TestTool
项目地址 : https://github.com/kelin-xycs/Socket-Vs-WebSocket-TestTool Socket-Vs-WebSocket-TestTool 一个用 ...