Crosser @ 2024-11-28 17:12:59
As shown.
#include <bits/stdc++.h>
// #define int long long
using namespace std;
int len(int l, int r) { return r - l + 1; }
int ls(int u) { return u << 1; }
int rs(int u) { return u << 1 | 1; }
const int MAXN = 2e5 + 5;
int N, M, R, P;
vector<int> g[MAXN];
int val[MAXN];
//..dfs1
int fa[MAXN], dep[MAXN], sz[MAXN], hson[MAXN];
void dfs1(int u, int depth, int father) {
dep[u] = depth;
sz[u] = 1;
fa[u] = father;
hson[u] = -1;
for (auto x : g[u])
if (x != father) {
dfs1(x, depth + 1, u);
sz[u] += sz[x];
if (hson[x] == -1 || sz[x] > sz[hson[u]])
hson[u] = x;
}
}
//..dfs2
int dfnum = 0;
int dfn[MAXN], top[MAXN], rnk[MAXN];
void dfs2(int u, int chtop) {
top[u] = chtop;
dfn[u] = ++dfnum;
rnk[dfn[u]] = u;
if (sz[u] != 1) {
dfs2(hson[u], chtop);
for (auto x : g[u])
if (x != fa[u])
if (x != hson[u])
dfs2(x, x);
}
}
class Segtree {
private:
int n;
vector<int> s, t;
void maketag(const int k, int u, int l, int r) {
// cout << l << ' ' << r << endl;
s[u] += len(l, r) * k % P;
s[u] %= P;
t[u] += k;
t[u] %= P;
}
void add(int u, int l, int r, const int L, const int R, const int k) {
if (r < L || l > R)
return;
if (l >= L && r <= R) {
maketag(k, u, l, r);
return;
}
int mid = l + r >> 1;
maketag(t[u], ls(u), l, mid);
maketag(t[u], rs(u), mid + 1, r);
t[u] = 0;
add(ls(u), l, mid, L, R, k);
add(rs(u), mid + 1, r, L, R, k);
s[u] = s[ls(u)] + s[rs(u)];
s[u] %= P;
}
int sum(int u, int l, int r, const int L, const int R) {
if (r < L || l > R)
return 0;
if (l >= L && r <= R)
return s[u];
int mid = l + r >> 1;
maketag(t[u], ls(u), l, mid);
maketag(t[u], rs(u), mid + 1, r);
t[u] = 0;
return (sum(ls(u), l, mid, L, R) + sum(rs(u), mid + 1, r, L, R)) % P;
}
public:
Segtree(int _size) {
n = _size, s.resize((_size + 1) << 2), t.resize((_size + 1) << 2);
}
void add(const int __l, const int __r, const int __value) {
add(1, 1, n, __l, __r, __value);
}
int sum(const int __l, const int __r) { return sum(1, 1, n, __l, __r); }
};
Segtree Tree(100);
int pw(int a, int b, int p) {
int res = 1;
while (b) {
if (b & 1) {
res *= a;
res %= p;
}
a *= a;
a %= p;
b /= 2;
}
return res;
}
void TrAdd(int u, int k) {
int l = dfn[u], r = dfn[u] + sz[u] - 1;
Tree.add(l, r, k);
}
int TrSum(int u) {
int l = dfn[u], r = dfn[u] + sz[u] - 1;
return Tree.sum(l, r);
}
void RoadAdd(int x, int y, int k) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])
swap(x, y);
Tree.add(dfn[top[x]], dfn[x], k);
x = fa[top[x]];
}
int l = min(dfn[x], dfn[y]);
int r = max(dfn[x], dfn[y]);
Tree.add(l, r, k);
}
int RoadSum(int x, int y) {
int res = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])
swap(x, y);
res += Tree.sum(dfn[top[x]], dfn[x]);
res %= P;
x = fa[top[x]];
}
int l = min(dfn[x], dfn[y]);
int r = max(dfn[x], dfn[y]);
res += Tree.sum(l, r);
res %= P;
return res;
}
signed main() {
std::ios::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
cin >> N >> M >> R >> P;
Tree = Segtree(N);
for (int i = 1; i <= N; i++)
cin >> val[i];
for (int i = 1; i < N; i++) {
int x, y;
cin >> x >> y;
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(R, 1, -1);
dfs2(R, R);
for (int i = 1; i <= N; i++) {
Tree.add(dfn[i], dfn[i], val[i]);
}
while (M--) {
int op, x, y, z;
cin >> op;
if (op == 1) {
cin >> x >> y >> z;
RoadAdd(x, y, z);
}
if (op == 2) {
cin >> x >> y;
cout << RoadSum(x, y) << endl;
}
if (op == 3) {
cin >> x >> z;
TrAdd(x, z);
}
if (op == 4) {
cin >> x;
cout << TrSum(x) << endl;
}
}
return 0;
}
Segment Tree 洛谷测模板题 200ms。
/kel /kel /kel /kel /kel /kel /kel
by luckyzjy @ 2024-11-28 17:18:26
是不是<<endl
by lg15166366290 @ 2024-11-28 18:10:53
#include <bits/stdc++.h>
// #define int long long
#define endl "\n"
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int len(int l, int r) { return r - l + 1; }
#define ls(u) (u<<1)
#define rs(u) (u<<1|1)
const int MAXN = 2e5 + 5;
int N, M, R, P;
vector<int> g[MAXN];
int val[MAXN];
//..dfs1
int fa[MAXN], dep[MAXN], sz[MAXN], hson[MAXN];
void dfs1(int u, int father) {
dep[u] = dep[father] + 1;
sz[u] = 1;
fa[u] = father;
for (auto x : g[u])
if (x != father) {
dfs1(x, u);
sz[u] += sz[x];
if (sz[x] > sz[hson[u]])
hson[u] = x;
}
}
//..dfs2
int dfnum = 0;
int dfn[MAXN], top[MAXN], rnk[MAXN];
void dfs2(int u, int chtop) {
top[u] = chtop;
dfn[u] = ++dfnum;
rnk[dfn[u]] = u;
if (sz[u] != 1) {
dfs2(hson[u], chtop);
for (auto x : g[u])
if (x != fa[u]&&x != hson[u])
dfs2(x, x);
}
}
struct Segtree {
int s[MAXN<<2], t[MAXN<<2];
void maketag(const int k, int u, int l, int r) {
// cout << l << ' ' << r << endl;
s[u] += len(l, r) * k % P;
s[u] %= P;
t[u] += k;
t[u] %= P;
}
void add(int u, int l, int r, const int L, const int R, const int k) {
if (l >= L && r <= R) {
maketag(k, u, l, r);
return;
}
int mid = l + r >> 1;
if(t[u])maketag(t[u], ls(u), l, mid);
if(t[u])maketag(t[u], rs(u), mid + 1, r);
t[u] = 0;
if(L<=mid)add(ls(u), l, mid, L, R, k);
if(R>mid)add(rs(u), mid + 1, r, L, R, k);
s[u] = s[ls(u)] + s[rs(u)];
s[u] %= P;
}
int sum(int u, int l, int r, const int L, const int R) {
if (l >= L && r <= R)
return s[u];
int mid = l + r >> 1;
if(t[u])maketag(t[u], ls(u), l, mid);
if(t[u])maketag(t[u], rs(u), mid + 1, r);
t[u] = 0;
int ret=0;
if(L<=mid)ret=(ret + sum(ls(u), l, mid, L, R) ) % P;
if(R>mid)ret=(ret + sum(rs(u), mid + 1, r, L, R)) % P;
return ret;
}
};
Segtree Tree;
void TrAdd(int u, int k) {
int l = dfn[u], r = dfn[u] + sz[u] - 1;
Tree.add(1, 1, N, l, r, k);
}
int TrSum(int u) {
int l = dfn[u], r = dfn[u] + sz[u] - 1;
return Tree.sum(1, 1, N, l, r);
}
void RoadAdd(int x, int y, int k) {
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])
swap(x, y);
Tree.add(1, 1, N, dfn[top[x]], dfn[x], k);
x = fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
Tree.add(1, 1, N, dfn[x], dfn[y], k);
}
int RoadSum(int x, int y) {
int res = 0;
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]])
swap(x, y);
res += Tree.sum(1, 1, N, dfn[top[x]], dfn[x]);
res %= P;
x = fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res += Tree.sum(1, 1, N, dfn[x], dfn[y]);
res %= P;
return res;
}
signed main() {
// cin >> N >> M >> R >> P;
N=read(), M=read(), R=read(), P=read();
for (int i = 1; i <= N; i++)
val[i]=read();
for (int i = 1; i < N; i++) {
int x=read(), y=read();
g[x].push_back(y);
g[y].push_back(x);
}
dfs1(R, 0);
dfs2(R, R);
for (int i = 1; i <= N; i++) {
Tree.add(1, 1, N, dfn[i], dfn[i], val[i]);
}
while (M--) {
int op, x, y, z;
op=read();
if (op == 1) {
x=read(), y=read(), z=read();
RoadAdd(x, y, z);
}
if (op == 2) {
x=read(), y=read();
cout << RoadSum(x, y) << endl;
}
if (op == 3) {
x=read(), z=read();
TrAdd(x, z);
}
if (op == 4) {
x=read();
cout << TrSum(x) << endl;
}
}
return 0;
}
by lg15166366290 @ 2024-11-28 18:11:31
@Crosser 改了哪已经忘了
by Crosser @ 2024-11-28 18:22:28
@lg15166366290 非常感谢 /bx
by Crosser @ 2024-11-28 18:46:34
@lg15166366290 好像只有 dfs1
的优化起效了?就是把 hson[u] = -1
和那个或去掉的一段。