SPOJ Problem Set (classical)375. Query on a treeProblem code: QTREE |
We will ask you to perfrom some instructions of the following form:
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.
For each test case:
There is one blank line between successive tests.
For each "QUERY" operation, write one integer representing its result.
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
| Added by: | Thanh-Vy Hua |
| Date: | 2005-06-08 |
| Time limit: | 5s |
| Source limit: | 15000B |
| Memory limit: | 256MB |
| Cluster: | Pyramid (Intel Pentium III 733 MHz) |
| Languages: | All except: AWK C++ 4.3.2 C99 strict CLOJ ERL F# GO JS NODEJS PERL 6 PYTH 3.2.3 PYTH 3.2.3 n SCALA SED TCL |
树链剖分+线段树
维护两点建路径上的边权最大值。。。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long int LL;
const int maxn=110000;
struct Edge
{
int to,next;
}edge[maxn*4];
int Adj[maxn],Size;
void init_edge()
{
memset(Adj,-1,sizeof(Adj)); Size=0;
}
void add_edge(int u,int v)
{
edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++;
}
int fa[maxn],deep[maxn],num[maxn],son[maxn];
int top[maxn],p[maxn],rp[maxn],pos;
void init()
{
init_edge();
memset(son,-1,sizeof(son));
pos=1;
}
void dfs1(int u,int pre,int d)
{
num[u]=1; fa[u]=pre; deep[u]=d;
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v==pre) continue;
dfs1(v,u,d+1);
num[u]+=num[v];
if(son[u]==-1||num[son[u]]<num[v])
son[u]=v;
}
}
void getPOS(int u,int to)
{
top[u]=to;
p[u]=pos++;
rp[p[u]]=u;
if(son[u]!=-1) getPOS(son[u],to);
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(v!=fa[u]&&v!=son[u])
getPOS(v,v);
}
}
int n;
int e[maxn][3];
///segTree
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int maxnum[maxn<<2];
void build(int l,int r,int rt)
{
maxnum[rt]=0;
if(l==r) return ;
int m=(l+r)/2;
build(lson);
build(rson);
}
void push_up(int rt)
{
maxnum[rt]=max(maxnum[rt<<1],maxnum[rt<<1|1]);
}
void update(int pos,int val,int l,int r,int rt)
{
if(l==pos&&r==pos)
{
maxnum[rt]=val;
return ;
}
int m=(l+r)/2;
if(pos<=m) update(pos,val,lson);
else update(pos,val,rson);
push_up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
return maxnum[rt];
}
int m=(l+r)/2;
int ret=0;
if(L<=m) ret=max(ret,query(L,R,lson));
if(R>m) ret=max(ret,query(L,R,rson));
return ret;
}
int find(int u,int v)
{
int f1=top[u],f2=top[v];
int ret=0;
while(f1!=f2)
{
if(deep[f1]<deep[f2])
{
swap(f1,f2); swap(u,v);
}
ret=max(ret,query(p[f1]-1,p[u]-1,1,n,1));
u=fa[f1]; f1=top[u];
}
if(u==v) return ret;
if(deep[u]>deep[v]) swap(u,v);
ret=max(ret,query(p[son[u]]-1,p[v]-1,1,n,1));
return ret;
}
void showit(int l,int r,int rt)
{
cout<<rt<<": "<<l<<" <---> "<<r<<" max: "<<maxnum[rt]<<endl;
if(l==r) return ;
int m=(l+r)/2;
showit(lson); showit(rson);
}
int main()
{
int T_T;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%d",&n);
init();
n--;
for(int i=1;i<=n;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
e[i][0]=a;e[i][1]=b;e[i][2]=c;
add_edge(a,b);
add_edge(b,a);
}
dfs1(1,1,0);
getPOS(1,1);
build(1,n,1);
for(int i=1;i<=n;i++)
{
if(deep[e[i][0]]>deep[e[i][1]])
swap(e[i][0],e[i][1]);
update(p[e[i][1]]-1,e[i][2],1,n,1);
}
char op[10];
while(scanf("%s",op)!=EOF)
{
if(op[0]=='Q')
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",find(a,b));
}
else if(op[0]=='C')
{
int a,b;
scanf("%d%d",&a,&b);
update(p[e[a][1]]-1,b,1,n,1);
}
else if(op[0]=='D')
{
putchar(10);
break;
}
}
}
return 0;
}
SPOJ QTREE 375. Query on a tree
原文:http://blog.csdn.net/ck_boss/article/details/39735563