社区讨论
题目数据是不是更新了
P3384【模板】重链剖分 / 树链剖分参与者 8已保存回复 11
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 11 条
- 当前快照
- 1 份
- 快照标识符
- @mi5i5g2p
- 此快照首次捕获于
- 2025/11/19 12:28 4 个月前
- 此快照最后确认于
- 2025/11/19 12:37 4 个月前
原来能AC的代码现在后三个点TLE,快速读入依然无解。
如果可以,请提供一下后三个点数据吧..
··cpp
CPP#include<iostream>
#include<cstdio>
using namespace std;
const int N=100005;
typedef long long ll;
int n,m,r,p;
int head[N],cnt;
struct node{
int to,ne;
}e[N*2];
int tot;
struct tree{
int l,r,ls,rs;
ll sum,tag;
}t[N*2];
int totw;
int a[N],b[N],fa[N],son[N],dep[N],size[N],st[N],ed[N],top[N];
int qread() {
int ret=0; char ch=getchar();
while(ch<'0' || ch>'9') ch=getchar();
while(ch>='0' && ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret;
}
int in(int x,int y) {
e[++cnt].to=y; e[cnt].ne=head[x]; head[x]=cnt;
}
/*树剖begin*/
void dfs1(int x) {
size[x]=1;
for(int i=head[x];i;i=e[i].ne) {
int y=e[i].to;
if(fa[x]==y) continue;
fa[y]=x; dep[y]=dep[x]+1;
dfs1(y); size[y]+=size[x];
if(size[son[x]]<size[y]) son[x]=y;
}
}
void dfs2(int x) {
st[x]=ed[x]=++totw;
int y=son[x];
if(!y) return;
top[y]=top[x]; dfs2(y);
for(int i=head[x];i;i=e[i].ne) {
int y=e[i].to;
if(fa[x]==y || son[x]==y) continue;
top[y]=y; dfs2(y);
}
ed[x]=totw;
}
/*树剖end*/
void update(int x) {
t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum;
}
int build(int l,int r) {
int now=++tot;
t[now].l=l,t[now].r=r;
if(l==r) {t[now].sum=b[l]; return now;}
int mid=l+r>>1;
t[now].ls=build(l,mid);
t[now].rs=build(mid+1,r);
update(now);
return now;
}
void pushdown(int now) {
int ls=t[now].ls,rs=t[now].rs;
if(t[now].tag) {
if(ls) {
t[ls].sum+=t[now].tag*ll(t[ls].r-t[ls].l+1);
t[ls].tag+=t[now].tag;
}
if(rs) {
t[rs].sum+=t[now].tag*ll(t[rs].r-t[rs].l+1);
t[rs].tag+=t[now].tag;
}
}
t[now].tag=0;
}
void plus_add(int now,int x,int y,ll d) {
pushdown(now);
int l=t[now].l,r=t[now].r;
if(x<=l && y>=r) {
t[now].tag+=d;
t[now].sum+=d*ll(t[now].r-t[now].l+1);
return;
}
int mid=l+r>>1;
if(x<=mid) plus_add(t[now].ls,x,y,d);
if(y>mid) plus_add(t[now].rs,x,y,d);
update(now);
}
ll get_sum(int now,int x,int y) {
pushdown(now);
int l=t[now].l,r=t[now].r;
if(x<=l && y>=r) return t[now].sum;
ll ans=0;
int mid=l+r>>1;
if(x<=mid) ans+=get_sum(t[now].ls,x,y)%p;
if(y>mid) ans+=get_sum(t[now].rs,x,y)%p;
update(now);
return ans;
}
int main() {
n=qread(); m=qread(); r=qread(); p=qread();
for(int i=1;i<=n;i++) a[i]=qread();
for(int i=1,x,y;i<n;i++) x=qread(),y=qread(),in(x,y),in(y,x);
dfs1(r); dfs2(r);
for(int i=1;i<=n;i++) b[st[i]]=a[i]%p;
int root=build(1,n);
for(int i=1;i<=m;i++) {
int x,y,op; ll z;
op=qread();
if(op==1) {
x=qread(),y=qread(),z=qread();
z%=p;
while(top[x]!=top[y]) {
if(dep[top[x]]<dep[top[y]]) swap(x,y);
plus_add(root,st[top[x]],st[x],z);
x=fa[top[x]];
}
if(st[x]>st[y]) swap(x,y);
plus_add(root,st[x],st[y],z);
}
if(op==2) {
x=qread(),y=qread();
ll ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=get_sum(root,st[top[x]],st[x])%p;
x=fa[top[x]];
}
if(st[x]>st[y]) swap(x,y);
ans+=get_sum(root,st[x],st[y])%p;
printf("%lld\n",ans%p);
}
if(op==3) {
x=qread(),z=qread();
z%=p;
plus_add(root,st[x],ed[x],z);
}
if(op==4) {
x=qread();
ll ans=0;
ans+=get_sum(root,st[x],ed[x]);
printf("%lld\n",ans%p);
}
}
return 0;
}
回复
共 11 条回复,欢迎继续交流。
正在加载回复...