您的位置:首页 > 其它

HDU 5274 Dylans loves tree 树链剖分+线段树

2017-04-10 15:01 453 查看

Dylans loves tree

[align=left][b]Problem Description[/b][/align]
Dylans is given a tree with N nodes.

All nodes have a value A[i].Nodes on tree is numbered by 1∼N.

Then he is given Q questions like that:

①0 x y:change node x′s value to y

②1 x y:For all the value in the path from x to y,do they all appear even times?

For each ② question,it guarantees that there is at most one value that appears odd times on the path.

1≤N,Q≤100000, the value A[i]∈N and A[i]≤100000

[align=left][b]Input[/b][/align]
In the first line there is a test number T.
(T≤3 and there is at most one testcase that N>1000)

For each testcase:

In the first line there are two numbers N and Q.

Then in the next N−1 lines there are pairs of (X,Y) that stand for a road from x to y.

Then in the next line there are N numbers A1..AN stand for value.

In the next Q lines there are three numbers(opt,x,y).

[align=left][b]Output[/b][/align]
For each question ② in each testcase,if the value all appear even times output "-1",otherwise output the value that appears odd times.

[align=left][b]Sample Input[/b][/align]

1
3 2
1 2
2 3
1 1 1
1 1 2
1 1 3

[align=left][b]Sample Output[/b][/align]

-1
1

Hint

If you want to hack someone,N and Q in your testdata must smaller than 10000,and you shouldn't print any space in each end of the line.

BC题目链接:点这里!

[b]题解:[/b]

  


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 1e6+10, M = 1e3+20, mod = 1e9+7, inf = 2e9;

int dep
,head
,t=1,sz
,fa
,indexS,top
,pos
;
struct ss{int to,next;}e[N*2];
int n;
void add(int u,int v)
{e[t].to = v;e[t].next = head[u];head[u] = t++;}
void dfs(int u) {
sz[u] = 1;
dep[u] = dep[fa[u]] + 1;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(to == fa[u]) continue;
fa[to] = u;
dfs(to);
sz[u] += sz[to];
}
}
void dfs(int u,int chain) {
int k = 0;
pos[u] = ++indexS;
top[u] = chain;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(dep[to] > dep[u] && sz[to] > sz[k])
k = to;
}
if(k == 0) return ;
dfs(k,chain);
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(dep[to] > dep[u] && k != to)
dfs(to,to);
}
}

int sum
,fposs
;
void push_up(int i,int ll,int rr) {
sum[i] = sum[ls] ^ sum[rs];
}
void build(int i,int ll,int rr) {
if(ll == rr) {
sum[i] = fposs[ll];
return ;
}
build(ls,ll,mid),build(rs,mid+1,rr);
push_up(i,ll,rr);
}
void update(int i,int ll,int rr,int x,int c) {
if(ll == rr) {
sum[i] = c;
return ;
}
if(x <= mid) update(ls,ll,mid,x,c);
else update(rs,mid+1,rr,x,c);
push_up(i,ll,rr);
}
int query(int i,int ll,int rr,int x,int y) {
if(ll == x && rr == y) {
return sum[i];
}
if(y <= mid) return query(ls,ll,mid,x,y);
else if(x > mid) return query(rs,mid+1,rr,x,y);
else return query(ls,ll,mid,x,mid)^query(rs,mid+1,rr,mid+1,y);
}
int query(int x,int y) {
int res = 0;
while(top[x] != top[y]) {
if(dep[top[x]] > dep[top[y]]) {
res ^= query(1,1,indexS,pos[top[x]],pos[x]);
x = fa[top[x]];
}
else {
res ^= query(1,1,indexS,pos[top[y]],pos[y]);
y = fa[top[y]];
}
}
if(dep[x] < dep[y])res ^= query(1,1,n,pos[x],pos[y]);
else res ^= query(1,1,n,pos[y],pos[x]);
return res;
}
int T,Q,a
;
void init() {
t = 1;
memset(fa,0,sizeof(fa));
memset(head,0,sizeof(head));
memset(dep,0,sizeof(dep));
memset(sz,0,sizeof(sz));
memset(top,0,sizeof(top));
memset(pos,0,sizeof(pos));
indexS = 0;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&Q);
init();
for(int i = 1; i < n; ++i) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1);
dfs(1,1);
for(int i = 1; i <= n; ++i) scanf("%d",&a[i]);
for(int i = 1; i <= n; ++i) fposs[pos[i]] = a[i]+1;
build(1,1,indexS);
while(Q--) {
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op == 0) {
update(1,1,indexS,pos[x],y+1);
} else {
printf("%d\n",query(x,y)-1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: