社区讨论
关于CF575B Brides的树剖解法
CF575B Bribes参与者 4已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @lobm49is
- 此快照首次捕获于
- 2023/10/29 23:15 2 年前
- 此快照最后确认于
- 2023/11/04 04:06 2 年前
RT,这一题的树剖解法能不能过。第二个点超时,不知道是我写的问题还是这题树剖过不掉。
代码如下,如果有错误,还请大佬指出。
CPP代码如下,如果有错误,还请大佬指出。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int N=100005;
int n,k;
int s[10*N];
int u[N],v[N],x[N];
struct node
{
int nxt;
int to;
}e[N<<1];
int head[N],tot;
int dep[N],fa[N],sz[N],son[N];
int dfn[N],rnk[N],tg[N],top[N],idx;
int sum1[N<<2],sum2[N<<2];
int tag1[N<<2],tag2[N<<2];
int ans;
inline void read(int &x)
{
int f=1;char c;
for(x=0,c=getchar();c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;
for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48); x*=f;
}
inline void add(int from,int to)
{
e[++tot].to=to;
e[tot].nxt=head[from];
head[from]=tot;
}
inline void dfs1(int x)
{
sz[x]=1;
son[x]=0;
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa[x]) continue;
dep[v]=dep[x]+1;
fa[v]=x;
dfs1(v);
sz[x]+=sz[v];
if(sz[son[x]]<sz[v]) son[x]=v;
}
return ;
}
inline void dfs2(int x,int tp)
{
dfn[x]=++idx;
rnk[idx]=x;
top[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].nxt)
{
int v=e[i].to;
if(v==fa[x]||v==son[x]) continue;
dfs2(v,v);
}
return ;
}
inline void pushup(int x)
{
sum1[x]=(sum1[x<<1]+sum1[x<<1|1])%mod;
sum2[x]=(sum2[x<<1]+sum2[x<<1|1])%mod;
}
inline void pushdown1(int x)
{
sum1[x<<1]=1ll*sum1[x<<1]*tag1[x]%mod;
sum1[x<<1|1]=1ll*sum1[x<<1|1]*tag1[x]%mod;
tag1[x<<1]=1ll*tag1[x<<1]*tag1[x]%mod;
tag1[x<<1|1]=1ll*tag1[x<<1|1]*tag1[x]%mod;
tag1[x]=1;
return ;
}
inline void pushdown2(int x)
{
sum2[x<<1]=sum2[x<<1]*tag2[x]%mod;
sum2[x<<1|1]=sum2[x<<1|1]*tag2[x]%mod;
tag2[x<<1]=tag2[x<<1]*tag2[x]%mod;
tag2[x<<1|1]=tag2[x<<1|1]*tag2[x]%mod;
tag2[x]=1;
return ;
}
inline void build(int x,int l,int r)
{
tag1[x]=tag2[x]=1;
if(l==r)
{
sum1[x]=sum2[x]=0;
if(tg[rnk[l]]==-1) sum1[x]=1;
if(tg[rnk[l]]==1) sum2[x]=1;
return ;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);return ;
}
inline void update1(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
sum1[x]=2ll*sum1[x]%mod;
tag1[x]=2ll*tag1[x]%mod;
return ;
}
int mid=l+r>>1;
pushdown1(x);
if(ql<=mid) update1(x<<1,l,mid,ql,qr);
if(qr>mid) update1(x<<1|1,mid+1,r,ql,qr);
pushup(x);return ;
}
inline void update2(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr)
{
sum2[x]=2ll*sum2[x]%mod;
tag2[x]=2ll*tag2[x]%mod;
return ;
}
int mid=l+r>>1;
pushdown2(x);
if(ql<=mid) update2(x<<1,l,mid,ql,qr);
if(qr>mid) update2(x<<1|1,mid+1,r,ql,qr);
pushup(x);return ;
}
inline int query1(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return sum1[x];
int mid=l+r>>1;
int rest=0;
pushdown1(x);
if(ql<=mid) rest+=query1(x<<1,l,mid,ql,qr);
if(qr>mid) rest+=query1(x<<1|1,mid+1,r,ql,qr);
pushup(x);
return rest%mod;
}
inline int query2(int x,int l,int r,int ql,int qr)
{
if(ql<=l&&r<=qr) return sum2[x];
int mid=l+r>>1;
int rest=0;
pushdown2(x);
if(ql<=mid) rest+=query2(x<<1,l,mid,ql,qr);
if(qr>mid) rest+=query2(x<<1|1,mid+1,r,ql,qr);
pushup(x);
return rest%mod;
}
inline int Tquery(int u,int v)
{
int rest=0;
while(top[u]!=top[v])
{
if(dep[top[u]]>dep[top[v]])
{
rest=(rest+query1(1,1,n,dfn[top[u]],dfn[u]))%mod;
update1(1,1,n,dfn[top[u]],dfn[u]);
u=fa[top[u]];
}
else
{
rest=(rest+query2(1,1,n,dfn[top[v]],dfn[v]))%mod;
update2(1,1,n,dfn[top[v]],dfn[v]);
v=fa[top[v]];
}
}
if(u==v) return rest;
if(dep[u]<dep[v])
{
rest=(rest+query2(1,1,n,dfn[u]+1,dfn[v]))%mod;
update2(1,1,n,dfn[u]+1,dfn[v]);
}
else
{
rest=(rest+query1(1,1,n,dfn[v]+1,dfn[u]))%mod;
update1(1,1,n,dfn[v]+1,dfn[u]);
}
return rest;
}
int main()
{
read(n);
for(int i=1;i<n;i++)
{
read(u[i]);read(v[i]);read(x[i]);
add(u[i],v[i]);
add(v[i],u[i]);
}
read(k);
for(int i=1;i<=k;i++) read(s[i]);
dfs1(1);dfs2(1,1);
for(int i=1;i<n;i++)
{
if(!x[i]) continue;
if(fa[v[i]]==u[i]) tg[v[i]]=-1;
else tg[u[i]]=1;
}
// for(int i=1;i<=n;i++) printf("%d ",tg[i]);
// puts("");
build(1,1,n);
ans=Tquery(1,s[1]);
// printf("%lld\n",ans);
for(int i=1;i<k;i++)
{
ans=(ans+Tquery(s[i],s[i+1]))%mod;
// printf("%lld\n",ans);
}
printf("%d\n",ans);
return 0;
}
回复
共 5 条回复,欢迎继续交流。
正在加载回复...