ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat (树链剖分+线段树)
题目链接:https://nanti.jisuanke.com/t/31714
题意:给你一棵树,初始全为0,有四种操作:
1.u-v乘x 2.u-v加x 3. u-v取反 4.询问u-v的和
思路:
除去第三个操作就是很简单的树链剖分+线段树多重标记下放,所以我们只要考虑怎么维护第三个操作就好了,
由题目给的取反可知:!x = (2^64-1) - x; 但是这样维护还是很麻烦,因为这道题是对2^64取模的,我们可以
尝试把这个式子转换成只有加法和乘法的,这样就可以将其和前面两个操作一起维护降低难度。
我们可以想到: (-x)%(2^64) = (2^64-1)*x%(2^64),那么式子就可以转换成:
!x = (2^64-1)*x + (2^64-1) 这样这个式子就只有乘法和加法操作,以及一个常数,然后带入多重标记维护就好了
数组要开 unsigned long long ,题目给的模数也很特殊,2^64, 因为unsigned long long 溢出的时候相当于对2^64
取模,那么我们就不需要取模操作了,直接运算就完事了。
实现代码:
#include<bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid int m = (l + r) >> 1
#define ll unsigned long long
const ll inf = ;
const int M = 2e5+; vector<int>g[M];
int n,cnt1,cnt,a[M];
int son[M],fa[M],head[M],siz[M],top[M],dep[M],tid[M];
ll sum[M<<],add[M<<],mul[M<<]; void dfs1(int u,int faz,int deep){
dep[u] = deep;
fa[u] = faz;
siz[u] = ;
for(int i = ;i < g[u].size();i++){
int v = g[u][i];
//cout<<v<<" ";
if(v != fa[u]){
dfs1(v,u,deep+);
siz[u] += siz[v];
if(son[u] == -||siz[v] > siz[son[u]])
son[u] = v;
}
}
} void dfs2(int u,int t){
top[u] = t;
tid[u] = ++cnt;
if(son[u] == -) return;
dfs2(son[u],t);
for(int i = ;i<g[u].size();i++){
int v = g[u][i];
if(v != son[u]&&v != fa[u])
dfs2(v,v);
}
} void pushup(int rt){
sum[rt] = sum[rt<<] + sum[rt<<|];
} void pushdown(int m,int rt){
add[rt<<] = add[rt<<]*mul[rt] + add[rt];
add[rt<<|] = add[rt<<|]*mul[rt]+add[rt];
mul[rt<<] = mul[rt<<]*mul[rt];
mul[rt<<|] = mul[rt<<|]*mul[rt];
sum[rt<<] = sum[rt<<]*mul[rt] + add[rt]*(m-(m>>));
sum[rt<<|] = sum[rt<<|]*mul[rt]+add[rt]*(m>>);
add[rt] = ; mul[rt] = ;
} void build(int l,int r,int rt){
add[rt] = ; mul[rt] = ;
if(l == r){
sum[rt] = ;
return;
}
mid;
build(lson); build(rson);
pushup(rt);
} void update(int L,int R,ll c,int v,int l,int r,int rt){
if(L <= l&&R >= r){
if(v == ){
sum[rt] = sum[rt]*c;
add[rt] = add[rt]*c;
mul[rt] = mul[rt]*c;
}
else if(v == ){
sum[rt] = sum[rt] + (ll)c*(r-l+);
add[rt] = add[rt]+c;
}
else if(v == ){
sum[rt] = inf*sum[rt] + (r-l+)*inf;
add[rt] = add[rt]*inf+inf;
mul[rt] *= inf;
}
return;
}
pushdown(r-l+,rt);
int m = (l + r) >> ;
if(L <= m) update(L,R,c,v,lson);
if(R > m) update(L,R,c,v,rson);
pushup(rt);
} ll query(int L,int R,int l,int r,int rt){
if(L <= l&&R >= r){
return sum[rt];
}
mid;
pushdown(r-l+,rt);
ll ret = ;
if(L <= m) ret += query(L,R,lson);
if(R > m) ret += query(L,R,rson);
return ret;
} void cover(int x,int y,ll c,int v){
int fx = top[x],fy = top[y];
while(fx!=fy){
if(dep[fx] < dep[fy]) swap(fx,fy),swap(x,y);
update(tid[fx],tid[x],c,v,,n,);
x = fa[fx];fx = top[x];
}
if(dep[x] < dep[y]) swap(x,y);
update(tid[y],tid[x],c,v,,n,);
} ll ask(int x,int y){ //求两结点路径上的权值和
int fx = top[x],fy = top[y];
ll ans = ;
while(fx != fy){
if(dep[fx] < dep[fy]) swap(fx,fy),swap(x,y);
ans += query(tid[fx],tid[x],,n,);
x = fa[fx]; fx = top[x];
}
ans += (dep[x] > dep[y])?query(tid[y],tid[x],,n,):query(tid[x],tid[y],,n,);
return ans;
} void init(){
cnt = cnt1 = ;
memset(son,-,sizeof(son));
dep[] = ; fa[] = ; siz[] = ;
} int main()
{
int x,q,op,l,r;
ll c;
while(scanf("%d",&n)!=EOF){
init();
// cout<<inf<<endl;
for(int i = ;i <= n;i ++){
scanf("%d",&x);
g[x].push_back(i);
}
dfs1(,,);
dfs2(,);
build(,n,);
scanf("%d",&q);
while(q--){
scanf("%d",&op);
if(op == ||op == ){
scanf("%d%d%llu",&l,&r,&c);
cover(l,r,c,op);
}
else if(op == ){
scanf("%d%d",&l,&r);
cover(l,r,,op);
}
else {
scanf("%d%d",&l,&r);
printf("%llu\n",ask(l,r));
}
}
for(int i = ;i <= n;i ++)
g[i].clear();
}
return ;
}
ACM-ICPC 2018 焦作赛区网络预赛 E Jiu Yuan Wants to Eat (树链剖分+线段树)的更多相关文章
- ACM-ICPC 2018 焦作赛区网络预赛 E. Jiu Yuan Wants to Eat (树链剖分-线性变换线段树)
树链剖分若不会的话可自行学习一下. 前两种操作是线性变换,模\(2^{64}\)可将线段树全部用unsigned long long 保存,另其自然溢出. 而取反操作比较不能直接处理,因为其模\(2^ ...
- ACM-ICPC 2018 焦作赛区网络预赛- G:Give Candies(费马小定理,快速幂)
There are N children in kindergarten. Miss Li bought them NNN candies. To make the process more inte ...
- ACM-ICPC 2018 焦作赛区网络预赛- L:Poor God Water(BM模板/矩阵快速幂)
God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...
- ACM-ICPC 2018 焦作赛区网络预赛
这场打得还是比较爽的,但是队友差一点就再过一题,还是难受啊. 每天都有新的难过 A. Magic Mirror Jessie has a magic mirror. Every morning she ...
- ACM-ICPC 2018 焦作赛区网络预赛J题 Participate in E-sports
Jessie and Justin want to participate in e-sports. E-sports contain many games, but they don't know ...
- ACM-ICPC 2018 焦作赛区网络预赛 K题 Transport Ship
There are NN different kinds of transport ships on the port. The i^{th}ith kind of ship can carry th ...
- ACM-ICPC 2018 焦作赛区网络预赛 L 题 Poor God Water
God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him t ...
- ACM-ICPC 2018 焦作赛区网络预赛 I题 Save the Room
Bob is a sorcerer. He lives in a cuboid room which has a length of AA, a width of BB and a height of ...
- ACM-ICPC 2018 焦作赛区网络预赛 H题 String and Times(SAM)
Now you have a string consists of uppercase letters, two integers AA and BB. We call a substring won ...
随机推荐
- Cordova套网站
用Cordova套网站,只修改Content的话,打包后的App,在点击后会打开浏览器,并没有在App中显示内容. 需要设置allow-navigation为 * <?xml version=' ...
- Java获取指定包名下的所有类的全类名的解决方案
最近有个需求需要获取一个指定包下的所有类的全类名,因此特意写了个获取指定包下所有类的全类名的工具类.在此记录一下,方便后续查阅 一.思路 通过ClassLoader来查找指定包 ...
- RNN介绍,较易懂
人类并不是每时每刻都从一片空白的大脑开始他们的思考.在你阅读这篇文章时候,你都是基于自己已经拥有的对先前所见词的理解来推断当前词的真实含义.我们不会将所有的东西都全部丢弃,然后用空白的大脑进行思考.我 ...
- Flutter - 自动生成Android & iOS图标
对于要发布的app来说,做图标是一个麻烦的事,你需要知道N个图标的分辨率,然后用PhotoShop一个个修改导出. PS好图标之后,按照各自的位置放进去. ********************** ...
- MongoDB日常运维操作命令小结
总所周知,MongoDB是一个NoSQL非数据库系统,即一个数据库可以包含多个集合(Collection),每个集合对应于关系数据库中的表:而每个集合中可以存储一组由列标识的记录,列是可以自由定义的, ...
- 分布式监控系统Zabbix--完整安装记录(7)-使用percona监控MySQL
前面已经介绍了分布式监控系统Zabbix-3.0.3-完整安装记录(2)-添加mysql监控,但是没有提供可以直接使用的Key,太过简陋,监控效果不佳.要想更加仔细的监控Mysql,业内同学们都会选择 ...
- rsync同步时,删除目标目录比源目录多余文件的方法(--delete)
在日常运维工作中,我们经常用到rsync这个同步神器.有时在同步两个目录时,会要求删除目标目录中比源目录多出的文件,这种情况下,就可用到rsync的--delete参数来实现这个需求了. 实例说明:在 ...
- Sprint 冲刺第三阶段第6-10天
这几天一直都在整理我们之前的内容,检查会不会有细节问题.例如界面跳转.颜色等. 因为一直没办法找到guitub存放位置.于是在这里存放一些主代码. MainActivity.java package ...
- iOS开发线程安全问题
先来看一下代码: - (void)viewDidLoad { [super viewDidLoad]; self.testStr = @"String initial complete&qu ...
- GCP试用到期再申请
目标 GCP的免费试用到期了.网传可以续用,看了教程,记录下来. 法一 应该可以直接用一个新gmail账号的.这个方法的难点可能在于注册新账号有门槛.我有一个很久以前注册过的,试着找回了密码,登入GC ...