tonyre @ 2023-11-16 08:19:20
求助,这份代码不开O2就可以A,问题出在哪里。
鄙人看了很久都没看出来。
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
const int MAXN=1e5+5;
struct Tree
{
int l,r;
int sum;
int lazy;
}tree[4*MAXN];
vector<int>to[MAXN];
int a[MAXN];
int son[MAXN],fa[MAXN],siz[MAXN],dep[MAXN];
int tp[MAXN],dfn[MAXN],rnk[MAXN],lst[MAXN];
int cnt;
int n,q,r,mod;
void dfs1(int u,int father)
{
siz[u]=1;
for(auto v:to[u])
{
if(v==father) continue;
fa[v]=u,dep[v]=dep[u]+1;
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[v]>siz[son[u]]) son[u]=v;
}
}
void dfs2(int u,int top)
{
tp[u]=top;
cnt++;
dfn[u]=cnt,rnk[cnt]=u;
if(!son[u]) return lst[u]=dfn[u],void();
dfs2(son[u],top);
lst[u]=lst[son[u]];
for(auto v:to[u])
{
if(v==son[u]||v==fa[u]) continue;
dfs2(v,v);
lst[u]=max(lst[u],lst[v]);
}
}
void update(int pos)
{
tree[pos].sum=(tree[pos<<1].sum+tree[pos<<1|1].sum)%mod;
}
void pushdown(int pos)
{
tree[pos<<1].sum=(tree[pos<<1].sum+(tree[pos<<1].r-tree[pos<<1].l+1)*tree[pos].lazy)%mod;
tree[pos<<1|1].sum=(tree[pos<<1|1].sum+(tree[pos<<1|1].r-tree[pos<<1|1].l+1)*tree[pos].lazy)%mod;
tree[pos<<1].lazy=(tree[pos<<1].lazy+tree[pos].lazy)%mod;
tree[pos<<1|1].lazy=(tree[pos<<1|1].lazy+tree[pos].lazy)%mod;
tree[pos].lazy=0;
}
void buildtree(int pos,int l,int r)
{
tree[pos].l=l,tree[pos].r=r;
if(l==r) return tree[pos].sum=a[rnk[l]]%mod,void();
int mid=(l+r)>>1;
buildtree(pos<<1,l,mid);
buildtree(pos<<1|1,mid+1,r);
update(pos);
}
void add(int pos,int s,int t,int x)
{
if(s<=tree[pos].l&&tree[pos].r<=t)
{
tree[pos].sum=(tree[pos].sum+(tree[pos].r-tree[pos].l+1)*x)%mod;
tree[pos].lazy=(tree[pos].lazy+x)%mod;
return;
}
pushdown(pos);
int mid=(tree[pos].l+tree[pos].r)>>1;
if(s<=mid) add(pos<<1,s,t,x);
if(t>mid) add(pos<<1|1,s,t,x);
update(pos);
}
int add_path(int u,int v,int x)
{
while(tp[u]!=tp[v])
{
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
add(1,dfn[tp[u]],dfn[u],x);
u=fa[tp[u]];
}
add(1,min(dfn[u],dfn[v]),max(dfn[u],dfn[v]),x);
}
int query(int pos,int s,int t)
{
if(s<=tree[pos].l&&tree[pos].r<=t) return tree[pos].sum;
pushdown(pos);
int mid=(tree[pos].l+tree[pos].r)>>1,res=0;
if(s<=mid) res=(res+query(pos<<1,s,t))%mod;
if(t>mid) res=(res+query(pos<<1|1,s,t))%mod;
return res;
}
int query_path(int u,int v)
{
int res=0;
while(tp[u]!=tp[v])
{
if(dep[tp[u]]<dep[tp[v]]) swap(u,v);
res=(res+query(1,dfn[tp[u]],dfn[u]))%mod;
u=fa[tp[u]];
}
res=(res+query(1,min(dfn[u],dfn[v]),max(dfn[u],dfn[v])))%mod;
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("P3384_11.in","r",stdin);
freopen("P3384.out","w",stdout);
#endif
cin>>n>>q>>r>>mod;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
to[u].push_back(v);
to[v].push_back(u);
}
dfs1(r,0);
dfs2(r,r);
buildtree(1,1,n);
for(int i=1;i<=q;i++)
{
int op;
cin>>op;
if(op==1)
{
int u,v,x;
cin>>u>>v>>x;
add_path(u,v,x);
}
else if(op==2)
{
int u,v;
cin>>u>>v;
cout<<query_path(u,v)<<endl;
}
else if(op==3)
{
int u,x;
cin>>u>>x;
add(1,dfn[u],lst[u],x);
}
else if(op==4)
{
int u;
cin>>u;
cout<<query(1,dfn[u],lst[u])<<endl;
}
}
return 0;
}
by Buried_Dream @ 2023-11-16 08:23:24
add_path 函数没有返回值
by Buried_Dream @ 2023-11-16 08:24:03
@tonyre add_path 在编译选项里加上 -Wall -std=c++14 -O2
即可发现
by CNS_5t0_0r2 @ 2023-11-16 08:24:28
@Buried_Dream 这个一般不影响(开 O2 后怎么样我就不知道了)
by Buried_Dream @ 2023-11-16 08:24:46
@5t0_0r2 什么玩意不影响,int 函数没返回值
by tonyre @ 2023-11-16 08:25:24
@Buried_Dream 感谢!
我开了 Wall 以为提示的是某个 void 函数无返回值(
by CNS_5t0_0r2 @ 2023-11-16 08:26:00
@Buried_Dream 是的,我之前用过(其他题目)int 函数没返回值照样过。
by Buried_Dream @ 2023-11-16 08:26:30
@5t0_0r2 建议你 Noip 也这样,RE非常好分数
by Buried_Dream @ 2023-11-16 08:27:24
@5t0_0r2 那是因为你没开O2啊,你开了O2就挂了,现在ccf的比赛都开O2
by Read_int @ 2023-11-16 08:30:19
@5t0_0r2 如果你真的认为的话建议你所有比赛都写个 #define void int
吧,我敬你为勇士
by CNS_5t0_0r2 @ 2023-11-16 08:31:42
@Read_int 6,除非是手滑,我**写 int 干嘛