HDU - 4010
题意
给一棵树,四个操作
1 x y x~y连一条边
2 x y 把x变成根,断开y跟他的父节点
3 w x y 把 x 到 y 路径上的点权加w
4 x y 查询 x ~ y 路径上的点权的最大值
我的zz问题
做这个题真的是脑抽
题要看对,2操作不是断开x跟y的边。题看错wa死了
2操作
void cut(int x,int y)
{
makeroot(x);
if(findroot(y) != x || node[y].fa != x || node[y].ch[0])
return;
node[y].fa =0 ;
node[x].ch[1] = 0;
update(x);
}
int solve(int x,int y)
{
makeroot(x);
if(findroot(y) != x)
return 1;
splaying(y);
int p = node[y].ch[0];
// while(node[p].ch[1])
// p = node[p].ch[1];
// cut(p,y);
node[p].fa =0 ;
node[y].ch[0] = 0;
return 0;
}
可能是我lct不够熟练(这才是做的第二道题)
上面代码注释掉的wa,改成下面的就ac。
原因:没有down( p ) … … . . . … . . … . … 菜到了极点。
应该是
int solve(int x,int y)
{
makeroot(x);
if(findroot(y) != x)
return 1;
splaying(y);
int p = node[y].ch[0];
while(node[p].ch[1])
{
down(p);
p = node[p].ch[1];
}
cut(p,y);
// node[p].fa =0 ;
// node[y].ch[0] = 0;
return 0;
}
就可以ac 。
烦烦烦烦烦烦
#include<algorithm>
#include<iostream>
#include <cstdio>
#include <string>
#include <queue>
#include <cstring>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <unordered_set>
#include <climits>
#include <cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<double,double> pdd;
typedef unsigned long long ull;
typedef unordered_set<int>::iterator sit;
#define st first
#define sd second
#define mkp make_pair
#define pb push_back
void tempwj(){freopen("hash.in","r",stdin);freopen("hash.out","w",stdout);}
ll gcd(ll a,ll b){return b == 0 ? a : gcd(b,a % b);}
ll qpow(ll a,ll b,ll mod){a %= mod;ll ans = 1;while(b > 0){if(b & 1)ans = ans * a % mod;a = a * a % mod;b >>= 1;}return ans;}
struct cmp{bool operator()(const pii & a, const pii & b){return a.second > b.second;}};
int lb(int x){return x & -x;}
//friend bool operator < (Node a,Node b) 重载
const int inf = INT_MAX;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9+7;
const int maxn = 6e5+10;
const int M = 1e6 + 2;
struct Node
{
int ch[2],val,maxx,siz,fa,rev,tag;
}node[maxn];
bool ntroot(int no)
{
return node[node[no].fa].ch[0] == no || node[node[no].fa].ch[1] == no;
}
void xiugai(int no)
{
swap(node[no].ch[0],node[no].ch[1]);
node[no].rev ^= 1;
}
void xiugai2(int no,int val)
{
node[no].val += val;
node[no].tag += val;
node[no].maxx += val;
}
void down(int no)
{
if(node[no].rev)
{
if(node[no].ch[0])
xiugai(node[no].ch[0]);
if(node[no].ch[1])
xiugai(node[no].ch[1]);
node[no].rev = 0;
}
if(node[no].tag)
{
if(node[no].ch[0])
xiugai2(node[no].ch[0],node[no].tag);
if(node[no].ch[1])
xiugai2(node[no].ch[1],node[no].tag);
node[no].tag = 0;
}
}
void update(int no)
{
node[no].siz = node[node[no].ch[0]].siz + node[node[no].ch[1]].siz + 1;
node[no].maxx = node[no].val;
if(node[no].ch[0])
node[no].maxx = max(node[no].maxx,node[node[no].ch[0]].maxx);
if(node[no].ch[1])
node[no].maxx = max(node[no].maxx,node[node[no].ch[1]].maxx);
}
int ident(int no,int fa)
{
return node[fa].ch[1] == no;
}
void connect(int x,int y,int f)
{
node[x].fa = y;
node[y].ch[f] = x;
}
void pushall(int no)
{
if(ntroot(no))
pushall(node[no].fa);
down(no);
}
void zxbl(int no)
{
if(no == 0)
return;
zxbl(node[no].ch[0]);
printf("%d ",node[no].val);
zxbl(node[no].ch[1]);
}
void debug(int no)
{
zxbl(no);
printf("\n");
}
void change(int x)
{
int f = node[x].fa;
int ff = node[f].fa;
int k = ident(x,f);
connect(node[x].ch[k^1],f,k);
node[x].fa = ff;
if(ntroot(f))
node[ff].ch[ident(f,ff)] = x;
connect(f,x,k^1);
update(f);
update(x);
}
void splaying(int x)
{
pushall(x);
while(ntroot(x))
{
int f = node[x].fa;
int ff = node[f].fa;
if(ntroot(f))
ident(f,ff)^ident(x,f) ? change(x) : change(f);
change(x);
}
}
void access(int x)
{
for (int y = 0; x; y = x,x = node[x].fa)
{
splaying(x);
node[x].ch[1] = y;
update(x);
}
}
void makeroot(int x)
{
access(x);
splaying(x);
xiugai(x);
}
int findroot(int x)
{
access(x);
splaying(x);
while(node[x].ch[0])
{
down(x);
x = node[x].ch[0];
}
splaying(x);
return x;
}
int link(int x,int y)
{
makeroot(x);
if(findroot(y) == x)
return 1;
node[x].fa = y;
return 0;
}
void cut(int x,int y)
{
makeroot(x);
if(findroot(y) != x || node[y].fa != x || node[y].ch[0])
return;
node[y].fa =0 ;
node[x].ch[1] = 0;
update(x);
}
void split(int x,int y)
{
makeroot(x);
access(y);
splaying(y);
}
int solve(int x,int y)
{
makeroot(x);
if(findroot(y) != x)
return 1;
splaying(y);
int p = node[y].ch[0];
while(node[p].ch[1])
{
down(p);
p = node[p].ch[1];
}
cut(p,y);
// node[p].fa =0 ;
// node[y].ch[0] = 0;
return 0;
}
int opchange(int x,int y,int val)
{
makeroot(x);
if(findroot(y) != x)
return 1;
split(x,y);
xiugai2(y,val);
return 0;
}
int opquery(int x,int y)
{
makeroot(x);
if(findroot(y) != x)
return -1;
split(x,y);
return node[y].maxx;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for (int i = 0; i <= n; i ++ )
{
node[i].siz = 1;
node[i].val = 0;
node[i].maxx = 0;
node[i].ch[0] = node[i].ch[1] = node[i].rev = node[i].tag = node[i].fa = 0;
}
node[0].siz = 0;
node[0].maxx = -inf;
for (int i = 1; i < n; i ++ )
{
int x,y;
scanf("%d%d",&x,&y);
link(x,y);
}
for (int i = 1; i<= n; i ++ )
{
int x;
scanf("%d",&x);
node[i].val = x;
node[i].maxx = x;
}
int q;
scanf("%d",&q);
while(q -- )
{
int f,x,y;
scanf("%d%d%d",&f,&x,&y);
if(f == 1)
{
if(link(x,y))
printf("-1\n");
}
else if(f == 2)
{
if(x == y || solve(x,y))
printf("-1\n");
}
else if(f == 3)
{
int w;
scanf("%d",&w);
if(opchange(y,w,x))
printf("-1\n");
}
else if(f == 4)
{
printf("%d\n",opquery(x,y));
}
// for (int i = 1; i <= n; i ++ )
// {
// if(!ntroot(i))
// debug(i);
// }
// printf("\n\n");
}
printf("\n");
}
}