Jiu Yuan Wants to Ea 2018icpc焦作网络预选赛E
Apale 9/17/2018
题目链接:https://nanti.jisuanke.com/t/31714
题意 :一棵树,n个点,初值均为0,有四个操作:
1 u v x 把u v路径上所有点乘以x
2 u v x 把u v路径上所有点加上x
3 u v 把u v路径上所有点的值按位取反
4 u v 查询u v路径上所有点的和
答案 %
分析:
除了3,1 2 4就是裸轻重链剖分 + 线段树维护区间和
赛后看了别人的题解才知道怎么处理3。取反就等价于
pushdown的时候要想清楚乘和加的先后, 每次初始化一定要根据n来。 全初始化T成智障...
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = (int)1e5 + 5;
typedef unsigned long long ull;
const ull inf = (1 << 64) - 1;
int N,fa[maxn],M;
vector<int> G[maxn];
int deep[maxn], son[maxn], siz[maxn];
void dfs1(int u)
{
siz[u] = 1;
son[u] = 0;
deep[u] = deep[fa[u]] + 1;
for (int v:G[u])
{
dfs1(v);
siz[u] += siz[v];
if (siz[v] > siz[son[u]])
son[u] = v;
}
}
int top[maxn],id[maxn],cnt;
void dfs2(int u,int t)
{
top[u] = t;
id[u] = ++cnt;
if (son[u])
dfs2(son[u],t);
for (int v:G[u])
{
if (v != son[u] && v != fa[u])
dfs2(v,v);
}
}
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
ull sum[maxn<<2],add[maxn<<2],mult[maxn<<2],rev[maxn<<2];
void pushdown(int rt,int l,int r)
{
add[rt<<1] *= mult[rt], add[rt<<1] += add[rt];
add[rt<<1|1] *= mult[rt], add[rt<<1|1] += add[rt];
mult[rt<<1] *= mult[rt];
mult[rt<<1|1] *= mult[rt];
sum[rt<<1] *= mult[rt], sum[rt<<1] += add[rt] * l;
sum[rt<<1|1] *= mult[rt], sum[rt<<1|1] += add[rt] * r;
add[rt] = 0;
mult[rt] = 1;
}
void update(int L,int R,ull v,int l,int r,int rt,int op)
{
if(L <= l && r <= R)
{
if(op == 1)
sum[rt] *= v, mult[rt] *= v, add[rt] *= v;
else if(op == 2)
sum[rt] += (ull)(r-l+1)*v, add[rt] += v;
else if(op == 3)
{
sum[rt] *= inf, sum[rt] += (r-l+1)*inf;
add[rt] *= inf, add[rt] += inf;
mult[rt] *= inf;
}
return ;
}
int m = l + r >> 1;
pushdown(rt,m-l+1,r-m);
if (L <= m)
update(L,R,v,ls,op);
if(R > m)
update(L,R,v,rs,op);
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
ull query(int L,int R,int l,int r,int rt)
{
if(L <= l && r <= R)
return sum[rt];
int m = l + r >> 1;
pushdown(rt,m-l+1,r-m);
ull ans = 0;
if (L <= m)
ans += query(L,R,ls);
if(R > m)
ans += query(L,R,rs);
return ans;
}
void upd(int u,int v,int op,ull val = 0)
{
while(top[u] != top[v])
{
if(deep[top[u]] < deep[top[v]])
swap(u,v);
update(id[top[u]],id[u],val,1,cnt,1,op);
u = fa[top[u]];
}
if(deep[u] > deep[v])
swap(u,v);
update(id[u],id[v],val,1,cnt,1,op);
}
ull que(int u,int v)
{
ull ans = 0;
while(top[u] != top[v])
{
if(deep[top[u]] < deep[top[v]])
swap(u,v);
ans += query(id[top[u]],id[u],1,cnt,1);
u = fa[top[u]];
}
if(deep[u] > deep[v])
swap(u,v);
ans += query(id[u],id[v],1,cnt,1);
return ans;
}
void build(int l,int r,int rt)
{
sum[rt] = add[rt] = 0;
mult[rt] = 1;
if(l == r)
return ;
int m = l + r >> 1;
build(ls);
build(rs);
}
void init()
{
cnt = 0;
}
int main()
{
int op,l,r;
ull val;
while (scanf("%d",&N) != EOF)
{
init();
for (int i = 2; i <= N; ++i)
{
scanf("%d",&fa[i]);
G[fa[i]].emplace_back(i);
}
scanf("%d",&M);
dfs1(1);
dfs2(1,1);
build(1,cnt,1);
while (M--)
{
scanf("%d%d%d",&op,&l,&r);
if(op != 4)
{
if(op != 3)
scanf("%llu",&val);
upd(l,r,op,val);
}
else
printf("%llu\n",que(l,r));
}
for(int i=1;i<=N;++i)
G[i].clear();
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180