呀智障选手都快忘了代码怎么打了..
GDOI2017D3T4.. dwjshift说很像这道题,然后就去做了..
然后就做了半个月??
就是两棵LCT,一棵维护树的结构,一棵维护权值,两棵树在中序遍历上映射,所以维护一下根对根的映射即可
对于当前点$x$,在把它旋到当前splay的根的时候可以知道它在这棵splay上的排名
然后就去找对应的那棵权值splay的排名就知道映射的是哪个了啊..
然后.. 就没有然后了吧..
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL long long
using namespace std;
const LL Maxn = 50010;
struct node {
LL y, next;
}a[Maxn*2]; LL first[Maxn], len;
LL _max(LL x, LL y) { return x > y ? x : y; }
LL _min(LL x, LL y) { return x < y ? x : y; }
void ins(LL x, LL y) {
len++;
a[len].y = y;
a[len].next = first[x]; first[x] = len;
}
LL n, m, r;
LL p[Maxn];
LL Maxx[Maxn], Minn[Maxn], sum[Maxn], val[Maxn];
LL vfa[Maxn], fa[Maxn], sizef[Maxn], sizev[Maxn];
LL cf[Maxn][2], cv[Maxn][2];
LL revf[Maxn], revv[Maxn], la[Maxn];
LL sta[Maxn], tp;
char s[10];
void dfs(LL x) {
p[x] = x; sizef[x] = sizev[x] = 1;
for(LL k = first[x]; k; k = a[k].next){
LL y = a[k].y;
if(y == fa[x]) continue;
fa[y] = x; vfa[y] = x;
dfs(y);
}
}
LL rt;
/*f*/
bool is_rootf(LL x) { return cf[fa[x]][0] != x && cf[fa[x]][1] != x; }
void push_downf(LL x) {
if(revf[x]){
swap(cf[x][0], cf[x][1]);
revf[cf[x][0]] ^= 1; revf[cf[x][1]] ^= 1;
revf[x] = 0;
}
}
void prepf(LL x) {
LL i; tp = 0;
for(i = x; !is_rootf(i); i = fa[i]) sta[++tp] = i;
sta[++tp] = i;
for(i = tp; i >= 1; i--) push_downf(sta[i]);
}
void updatef(LL x) { sizef[x] = sizef[cf[x][0]]+sizef[cf[x][1]]+1; }
void rotatef(LL x) {
LL y = fa[x], z = fa[y], l, r;
if(cf[y][0] == x) l = 0; else l = 1; r = l^1;
if(!is_rootf(y)){ if(cf[z][0] == y) cf[z][0] = x; else cf[z][1] = x; }
fa[x] = z; fa[y] = x; fa[cf[x][r]] = y;
cf[y][l] = cf[x][r]; cf[x][r] = y;
updatef(y);
}
void splayf(LL x) {
rt = x;
prepf(x);
while(!is_rootf(x)){
LL y = fa[x], z = fa[y];
if(!is_rootf(y)){
if(is_rootf(z)) rt = z;
if((cf[z][0] == y)^(cf[y][0] == x)) rotatef(x);
else rotatef(y);
} else rt = y;
rotatef(x);
}
updatef(x);
}
/*v*/
bool is_rootv(LL x) { return cv[vfa[x]][0] != x && cv[vfa[x]][1] != x; }
void push_downv(LL x) {
if(revv[x]){
swap(cv[x][0], cv[x][1]);
revv[cv[x][0]] ^= 1; revv[cv[x][1]] ^= 1;
revv[x] = 0;
}
if(la[x] > 0){
if(cv[x][0] > 0){
sum[cv[x][0]] += sizev[cv[x][0]]*la[x]; val[cv[x][0]] += la[x];
Maxx[cv[x][0]] += la[x];
Minn[cv[x][0]] += la[x];
la[cv[x][0]] += la[x];
} if(cv[x][1] > 0){
sum[cv[x][1]] += sizev[cv[x][1]]*la[x]; val[cv[x][1]] += la[x];
Maxx[cv[x][1]] += la[x];
Minn[cv[x][1]] += la[x];
la[cv[x][1]] += la[x];
}
la[x] = 0;
}
}
void prepv(LL x) {
LL i; tp = 0;
for(i = x; !is_rootv(i); i = vfa[i]) sta[++tp] = i;
sta[++tp] = i;
for(i = tp; i >= 1; i--) push_downv(sta[i]);
}
void updatev(LL x) {
Maxx[x] = _max(Maxx[cv[x][0]], _max(Maxx[cv[x][1]], val[x]));
Minn[x] = _min(Minn[cv[x][0]], _min(Minn[cv[x][1]], val[x]));
sum[x] = sum[cv[x][0]]+sum[cv[x][1]]+val[x];
sizev[x] = sizev[cv[x][0]]+sizev[cv[x][1]]+1;
}
void rotatev(LL x) {
LL y = vfa[x], z = vfa[y], l, r;
if(cv[y][0] == x) l = 0; else l = 1; r = l^1;
if(!is_rootv(y)){ if(cv[z][0] == y) cv[z][0] = x; else cv[z][1] = x; }
vfa[x] = z; vfa[y] = x; vfa[cv[x][r]] = y;
cv[y][l] = cv[x][r]; cv[x][r] = y;
updatev(y);
}
void splayv(LL x) {
prepv(x);
while(!is_rootv(x)){
LL y = vfa[x], z = vfa[y];
if(!is_rootv(y)){
if((cv[z][0] == y)^(cv[y][0] == x)) rotatev(x);
else rotatev(y);
}
rotatev(x);
}
updatev(x);
}
LL find_rank(LL x, LL p) {
push_downv(x);
if(sizev[cv[x][0]]+1 == p) return x;
if(sizev[cv[x][0]] >= p) return find_rank(cv[x][0], p);
else return find_rank(cv[x][1], p-sizev[cv[x][0]]-1);
}
void splay(LL x) {
splayf(x);
LL o = find_rank(p[rt], sizef[cf[x][0]]+1);
splayv(o);
p[x] = o;
}
void access(LL x) {
LL tf = 0, tv = 0;
while(x){
splay(x);
LL o = p[x];
p[cf[x][1]] = cv[o][1];
cf[x][1] = tf;
cv[o][1] = tv;
if(tv) vfa[tv] = o;
tv = o;
tf = x;
x = fa[x];
}
}
void make_root(LL x) { access(x); splay(x); revf[x] ^= 1; revv[p[x]] ^= 1; }
void getchain(LL x, LL y) { make_root(x); access(y); splay(y); }
LL getsum(LL x, LL y) { getchain(x, y); return sum[p[y]]; }
LL getmin(LL x, LL y) { getchain(x, y); return Minn[p[y]]; }
LL getmax(LL x, LL y) { getchain(x, y); return Maxx[p[y]]; }
void add(LL x, LL y, LL c) { getchain(x, y); sum[p[y]] += sizev[p[y]]*c; val[p[y]] += c; Maxx[p[y]] += c; Minn[p[y]] += c; la[p[y]] += c; }
void invert(LL x, LL y) { getchain(x, y); revv[p[y]] ^= 1; }
int main() {
LL i, j, k;
Maxx[0] = -0x7fffffff; Minn[0] = 0x7fffffff;
scanf("%lld%lld%lld", &n, &m, &r);
for(i = 1; i < n; i++){
LL x, y;
scanf("%lld%lld", &x, &y);
ins(x, y); ins(y, x);
}
dfs(r);
for(i = 1; i <= m; i++){
scanf("%s", s+1);
if(s[1] == ‘I‘ && s[3] == ‘c‘){
LL x, y, c;
scanf("%lld%lld%lld", &x, &y, &c);
add(x, y, c);
} else if(s[1] == ‘S‘){
LL x, y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", getsum(x, y));
} else if(s[1] == ‘M‘ && s[2] == ‘a‘){
LL x, y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", getmax(x, y));
} else if(s[1] == ‘M‘){
LL x, y;
scanf("%lld%lld", &x, &y);
printf("%lld\n", getmin(x, y));
} else {
LL x, y;
scanf("%lld%lld", &x, &y);
invert(x, y);
}
}
return 0;
}
原文:http://www.cnblogs.com/darklove/p/6874869.html