社区讨论
求debug
P2590[ZJOI2008] 树的统计参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lrsm20lt
- 此快照首次捕获于
- 2024/01/25 10:44 2 年前
- 此快照最后确认于
- 2024/01/25 12:43 2 年前
代码在最后输出时有问题,求改正
CPP#include<bits/stdc++.h>
using namespace std;
int n,a,b;
int wver[30010],whead[30010],wnext[30010];
int tot,wtime;//时间戳
int fa[30010];//父节点
int dep[30010];//深度
int wsize[30010];//节点个数
int son[30010];//重儿子
int top[30010];//当前重链的顶点
int seg[30010];//当前点在线段树中的点
int rev[30010];//线段树中的点在实际中的点
struct TREE//线段树
{
int l,r,dat;
}tree1[60020];
TREE tree2[60020];
int w[30010];
void add(int x,int y)
{
wver[tot++]=y;//子节点
wnext[x]=whead[x];//下一个子节点
whead[x]=tot;//最后一个输入的子节点
}
void dfs1(int x,int pa)
{
wsize[x]=1;
fa[x]=pa;
dep[x]=dep[pa]+1;
for(int i=whead[x];i;i=wnext[i])
{
int y=wver[i];
if(y!=pa)
{
dfs1(y,x);
wsize[x]+=wsize[y];//累加自身节点个数
if(wsize[y]>wsize[son[x]])
{
wsize[son[x]]=wsize[y];
}
}
}
return;
}
void dfs2(int x)
{
if(son[x])//走重儿子
{
seg[son[x]]=++wtime;//线段树标记
top[son[x]]=top[x];//顶点标记
rev[wtime]=son[x];//映射标记
dfs2(son[x]);
}
for(int i=whead[x];i;i=wnext[i])
{
int y=wver[i];
if(!son[y])
{
seg[y]=++wtime;//线段树标记
top[y]=y;//顶点自我标记
rev[wtime]=y;//映射标记
dfs2(y);
}
}
return;
}
void set1(int p,int l,int r)//建线段树(sum)
{
tree1[p].l=l;
tree1[p].r=r;
if(l==r)
{
tree1[p].dat=w[l];
return;
}
int mid=(l+r)/2;
set1(p*2,l,mid);
set1(p*2+1,mid+1,r);
tree1[p].dat=tree1[p*2].dat+tree1[p*2+1].dat;
return;
}
void set2(int p,int l,int r)//建线段树(max)
{
tree1[p].l=l;
tree1[p].r=r;
if(l==r)
{
tree1[p].dat=w[l];
return;
}
int mid=(l+r)/2;
set2(p*2,l,mid);
set2(p*2+1,mid+1,r);
tree2[p].dat=max(tree1[p*2].dat,tree1[p*2+1].dat);
return;
}
int ask3(int p,int l,int r,int pd)//线段树查询
{
if(pd==1)//(sum)
{
if(l<=tree1[p].l&&r>=tree1[p].r)
return tree1[p].dat;
int mid=(tree1[p].l+tree1[p].r)/2;
int val=-(1<<30);
if(l<=mid)
{
val+=ask3(p*2,l,r,pd);
}
if(r>mid)
{
val+=ask3(p*2+1,l,r,pd);
}
return val;
}
else//(max)
{
if(l<=tree2[p].l&&r>=tree2[p].r)
return tree2[p].dat;
int mid=(tree2[p].l+tree2[p].r)/2;
int val=-(1<<30);
if(l<=mid)
{
val=max(val,ask3(p*2,l,r,pd));
}
if(r>mid)
{
val=max(val,ask3(p*2+1,l,r,pd));
}
return val;
}
}
int ask1(int u,int v)//求最大权值
{
int suml=0;
if(top[u]==top[v])
{
if(seg[u]>seg[v])
{
int g=u;
u=v;
v=g;
}
suml=max(suml,ask3(1,seg[u],seg[v],2));
}
else
{
while(top[u]!=top[v])
{
if(dep[u]>dep[v])
{
suml=max(suml,ask3(1,top[u],seg[u],2));
u=fa[top[u]];
}
else
{
suml=max(suml,ask3(1,top[v],seg[v],2));
v=fa[top[v]];
}
}
if(seg[u]>seg[v])
{
int g=u;
u=v;
v=g;
}
suml=max(suml,ask3(1,seg[u],seg[v],2));
}
return suml;
}
int ask2(int u,int v)//求路径权值和
{
int suml=0;
while(top[u]!=top[v])
{
if(dep[u]>dep[v])
{
suml+=ask3(1,top[u],seg[u],1);
u=fa[top[u]];
}
else
{
suml+=ask3(1,top[v],seg[v],1);
v=fa[top[v]];
}
}
if(seg[u]>seg[v])
{
int g=u;
u=v;
v=g;
}
suml+=ask3(1,seg[u],seg[v],1);
return suml;
}
int main()
{
cin>>n;
for(int i=0;i<n;++i)
{
cin>>a>>b;
add(a,b);
add(b,a);
}
for(int i=1;i<=n;++i)
{
cin>>w[i];
}
dfs1(1,1);
wtime=1;
top[1]=1;
seg[1]=1;
rev[1]=1;
dfs2(1);
set1(1,1,n);
set2(1,1,n);
//初始化完成
int q;
cin>>q;
string s;
int u,v;
for(int T=0;T<q;++T)
{
cin>>s;
cin>>u>>v;
if(s[0]=='C')
{
w[u]=v;
}
else if(s=="QMAX")
{//对应操作II
cout<<ask1(u,v)<<endl;
//cout<<"???";
}
else
{//对应操作III
cout<<ask2(u,v)<<endl;
cout<<"???";//这里循环输出
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...