POJ-3237-Tree
5317 단어 체인 분할
코드:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+100;
const int maxm=maxn*2;
struct Edge
{
int from;
int to;
int cost;
}E[maxn];
struct Node
{
int l;
int r;
int maxi;
int mini;
int neg;
}t[maxn*4];
int e,head[maxn],pnt[maxm],nxt[maxm],cost[maxm];
int n,pre[maxn],size[maxn],son[maxn],dep[maxn],top[maxn],idx[maxn],pos[maxn],tree_clock;
void AddEdge(int u,int v,int c)
{
pnt[e]=v;nxt[e]=head[u];cost[e]=c;head[u]=e++;
}
void Init()
{
e=tree_clock=0;
memset(head,-1,sizeof(head));
memset(dep,0,sizeof(dep));
pre[1]=0;
size[0]=0;
}
void DFS(int u)
{
size[u]=1;
son[u]=0;
for(int i=head[u];i!=-1;i=nxt[i])
if(pnt[i]!=pre[u])
{
pre[pnt[i]]=u;
dep[pnt[i]]=dep[u]+1;
DFS(pnt[i]);
size[u]+=size[pnt[i]];
if(size[pnt[i]]>size[son[u]])
son[u]=pnt[i];
}
}
void dfs(int u,int top_node)
{
top[u]=top_node;
pos[u]=++tree_clock;
idx[tree_clock]=u;
if(son[u])
dfs(son[u],top_node);
for(int i=head[u];i!=-1;i=nxt[i])
if(pnt[i]!=pre[u]&&pnt[i]!=son[u])
dfs(pnt[i],pnt[i]);
}
void Build(int l,int r,int index)
{
t[index].l=l;
t[index].r=r;
t[index].maxi=-inf;
t[index].mini=inf;
t[index].neg=0;
if(l==r)
return;
int mid=(l+r)>>1;
Build(l,mid,index<<1);
Build(mid+1,r,index<<1|1);
}
void UpdateNode(int index)
{
swap(t[index].maxi,t[index].mini);
t[index].maxi*=-1;
t[index].mini*=-1;
}
void PushDown(int index)
{
if(t[index].l==t[index].r)
return;
if(t[index].neg)
{
t[index<<1].neg^=1;
t[index<<1|1].neg^=1;
UpdateNode(index<<1);
UpdateNode(index<<1|1);
t[index].neg=0;
}
}
void PushUp(int index)
{
t[index].maxi=max(t[index<<1].maxi,t[index<<1|1].maxi);
t[index].mini=min(t[index<<1].mini,t[index<<1|1].mini);
}
void UpdateT(int l,int r,int index,int val)
{
PushDown(index);
if(t[index].l==l&&t[index].r==r)
{
if(val==inf)
{
t[index].neg=1;
UpdateNode(index);
}
else
t[index].mini=t[index].maxi=val;
return;
}
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
UpdateT(l,r,index<<1,val);
else if(l>mid)
UpdateT(l,r,index<<1|1,val);
else
{
UpdateT(l,mid,index<<1,val);
UpdateT(mid+1,r,index<<1|1,val);
}
PushUp(index);
}
int QueryT(int l,int r,int index)
{
PushDown(index);
if(t[index].l==l&&t[index].r==r)
return t[index].maxi;
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
return QueryT(l,r,index<<1);
else if(l>mid)
return QueryT(l,r,index<<1|1);
else
return max(QueryT(l,mid,index<<1),QueryT(mid+1,r,index<<1|1));
}
void Update(int x,int y,int v)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
UpdateT(pos[top[x]],pos[x],1,v);
x=pre[top[x]];
}
if(x==y)
return;
if(dep[x]>dep[y])
swap(x,y);
UpdateT(pos[son[x]],pos[y],1,v);
}
int Query(int x,int y)
{
int ans=-inf;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
ans=max(ans,QueryT(pos[top[x]],pos[x],1));
x=pre[top[x]];
}
if(x==y)
return ans;
if(dep[x]>dep[y])
swap(x,y);
ans=max(ans,QueryT(pos[son[x]],pos[y],1));
return ans==-inf?0:ans;
}
void solve()
{
DFS(1);
dfs(1,1);
Build(1,tree_clock,1);
for(int i=1;i<n;i++)
{
int x=E[i].from;
int y=E[i].to;
if(dep[x]>dep[y])
swap(E[i].from,E[i].to);
UpdateT(pos[E[i].to],pos[E[i].to],1,E[i].cost);
}
while(1)
{
char op[20];
scanf("%s",op);
if(op[0]=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d
",Query(l,r));
}
else if(op[0]=='C')
{
int ind,val;
scanf("%d%d",&ind,&val);
UpdateT(pos[E[ind].to],pos[E[ind].to],1,val);
}
else if(op[0]=='N')
{
int l,r;
scanf("%d%d",&l,&r);
Update(l,r,inf);
}
else
break;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Init();
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d%d",&E[i].from,&E[i].to,&E[i].cost);
AddEdge(E[i].from,E[i].to,E[i].cost);
AddEdge(E[i].to,E[i].from,E[i].cost);
}
solve();
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[BZOJ3531] [Sdoi 2014] 여행 나무 사슬 분할.세그먼트 트리 10W를 열고 노드를 동적으로 추가합니다.그런 다음 개별 세그먼트 트리 횡단을 수행합니다. 세상에!!CFree가 뜻밖에도 나에게 '&' 기호를 삼켰다.징그러워. 한참 찾았는데....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.