如题,写的线段树过了线段树1的模板 但是MLE了,前9个点都AC了,最后一个不知道为什么MLE了。。。
#include <stdio.h>
#include <algorithm>
#define MAXN 100866
using namespace std;
int p;
int w[MAXN];
int nw[MAXN];
int nid[MAXN];
//线段树部分
struct segNode
{
long long val,lazy;
int l,r;
}segT[MAXN * 4 + 2];
void buildSeg(int o,int L,int R)
{
segT[o].l = L;
segT[o].r = R;
if(L == R)
{
segT[o].val = nw[L] % p;
return;
}
int m = (segT[o].l % p + ((segT[o].r % p - segT[o].l % p) / 2)) % p;
buildSeg(2 * o,L,m);
buildSeg(2 * o + 1,m + 1,R);
segT[o].val = (segT[2 * o].val % p + segT[2 * o + 1].val % p) % p;
}
void spread(int o)
{
if(!segT[o].lazy)
return;
segT[2 * o].val += ((segT[2 * o].r % p - segT[2 * o].l + 1 % p) * segT[o].lazy % p) % p;
segT[2 * o].lazy += segT[o].lazy % p;
segT[2 * o + 1].val += ((segT[2 * o + 1].r % p - segT[2 * o + 1].l % p + 1 % p) * segT[o].lazy % p) % p;
segT[2 * o + 1].lazy += segT[o].lazy % p;
segT[o].lazy = 0 % p;
}
void update(int o,int L,int R,int v)
{
//if(v == 0)return;
if(L <= segT[o].l && R >= segT[o].r)
{
segT[o].lazy += v % p;
segT[o].val += ((segT[o].r % p - segT[o].l % p + 1 % p) * v % p) % p;
return;
}
spread(o);
int m = segT[o].l % p + (segT[o].r % p - segT[o].l % p) / 2;
if(m >= L)
{
update(2 * o,L,R,v);
}
if(m < R)
{
update(2 * o + 1,L,R,v);
}
segT[o].val = segT[o * 2].val + segT[o * 2 + 1].val;
}
long long query(int o,int L,int R)
{
long long ans = 0;
if(L <= segT[o].l && R >= segT[o].r)
{
return segT[o].val % p;
}
spread(o);
int m = (segT[o].l % p + (segT[o].r % p - segT[o].l % p) / 2 % p) % p;
if(m >= L)
{
ans += query(2 * o,L,R) % p;
}
if(m < R)
{
ans += query(2 * o + 1,L,R) % p;
}
return ans % p;
}
//树链剖分部分
int hed[MAXN * 2 + 2],nxt[MAXN * 2 + 2],to[MAXN * 2 + 2],cnt = 1,pa[MAXN * 2 + 2];
void AddEdge(int u,int v)
{
nxt[cnt] = hed[u];
hed[u] = cnt;
to[cnt] = v % p;
cnt++;
}
int depth[MAXN],sonum[MAXN],son[MAXN];
//返回以该节点为根的子树的节点个数
int dfs1(int now,int fa)
{
pa[now] = fa;
depth[now] = depth[fa] + 1;
int maxsonn = 0;
sonum[now] = 1;
for(int i = hed[now]; i; i = nxt[i])
{
int y = to[i];
if(y == fa)
continue;
int nsn = dfs1(y,now);
if(nsn > maxsonn)
{
son[now] = y;
maxsonn = nsn;
}
sonum[now] += nsn;
}
return sonum[now];
}
int top[MAXN];
int idc = 1;
void dfs2(int now,int tope)
{
nid[now] = idc;
nw[idc] = w[now];
idc++;
top[now] = tope;
if(!son[now])
return;
dfs2(son[now],tope);
for(int i = hed[now]; i; i = nxt[i])
{
int y = to[i];
if(y == pa[now])
continue;
if(y == son[now])
continue;
dfs2(y,y);
}
}
//从x到y加z
void RoadAdd(int x,int y,int z)
{
while(top[x] != top[y])
{
if(depth[top[x]] < depth[top[y]])
swap(x,y);
update(1,nid[top[x]],nid[x],z);
x = pa[top[x]];
}
if(depth[x] < depth[y])
swap(x,y);
update(1,nid[y],nid[x],z);
}
//查从x到y
int RoadQuery(int x,int y)
{
int ans = 0;
while(top[x] != top[y])
{
if(depth[top[x]] < depth[top[y]])
swap(x,y);
ans += query(1,nid[top[x]],nid[x]) % p;
ans %= p;
x = pa[top[x]];
}
//exit(0);
if(depth[x] < depth[y])
swap(x,y);
ans += query(1,nid[y],nid[x]) % p;
return ans % p;
}
//增加以now为子树的所有节点的值和
void SubAdd(int now,int v)
{
update(1,nid[now],nid[now] + sonum[now] - 1,v);
}
int SubQuery(int now)
{
return query(1,nid[now],nid[now] + sonum[now] - 1) % p;
}
int main(void)
{
int n,m,r;
scanf("%d%d%d%d",&n,&m,&r,&p);
for(int i = 1; i <= n; i++)
{
scanf("%d",&w[i]);
}
for(int i = 0; i < n - 1; i++)
{
int x,y;
scanf("%d%d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
depth[r] = 1;
//exit(0);
dfs1(r,0);
dfs2(r,r);
buildSeg(1,1,n);
//SubQuery(r);
for(int i = 0; i < m; i++)
{
int op;
scanf("%d",&op);
if(op == 1)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
RoadAdd(x,y,z);/*
printf("\n");
for(int i = 1; i <= n; i++)
{
printf("%d ",query(1,nid[i],nid[i]));
}
printf("\n");*/
}
else
if(op == 2)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",RoadQuery(x,y));/*
printf("\n");
for(int i = 1; i <= n; i++)
{
printf("%d ",query(1,nid[i],nid[i]));
}
printf("\n");*/
}
else
if(op == 3)
{
int x,z;
scanf("%d%d",&x,&z);
SubAdd(x,z);/*
printf("\n");
for(int i = 1; i <= n; i++)
{
printf("%d ",query(1,nid[i],nid[i]));
}
printf("\n");*/
}
else
{
int x;
scanf("%d",&x);
printf("%d\n",SubQuery(x));/*
printf("\n");
for(int i = 1; i <= n; i++)
{
printf("%d ",query(1,nid[i],nid[i]));
}
printf("\n");*/
}
}
return 0;
}