学了树链剖分做的第二道练习题,这个题比较麻烦的是取反那,也就是每次乘以-1,同样的转成线段树进行维护,我在有个地方应该更新son[u],的时候直接+1了,导致WA了超多。
代码:
#include
#include
#include
#include
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[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[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;idep[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\n",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