Title:
Explanation:
I don't know what kind of strange things I've been stuck with for a long time
At one glance, the tree is cut, but the second question seems to be unfriendly. Since some chains are selected each time, their overlapping parts cannot be calculated, so the situation is more complex.
In fact, the transformation is to mark the points on the chain, and calculate the point weight sum of the marked points.
Since the flag of an interval is only 0 / 1, an array can be opened to maintain and when marking an interval.
Mark each segment corresponding to each chain in the segment tree, then count the weight sum of all marked points in the segment tree, and finally delete the marks of all points.
Time complexity O(Qklog2n)O(Qklog2n)
As for mod maxlongint, you can use int to overflow naturally. The final result and maxlongint are equal to each other.
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200005;
int tot,nxt[N*2],point[N],v[N*2],n,size[N],f[N],h[N],in[N],son[N],top[N],num,out[N],have[N*4],sum[N*4],delta[N*4],bb[N*4];
void addline(int x,int y)
{
++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;
++tot; nxt[tot]=point[y]; point[y]=tot; v[tot]=x;
}
void dfs_1(int x,int fa)
{
f[x]=fa; h[x]=h[fa]+1; size[x]=1;int maxx=0;
for (int i=point[x];i;i=nxt[i])
if (v[i]!=fa)
{
dfs_1(v[i],x);
size[x]+=size[v[i]];
if (maxx<size[v[i]]) maxx=size[v[i]],son[x]=v[i];
}
}
void dfs_2(int x,int fa)
{
if (son[fa]!=x) top[x]=x;
else top[x]=top[fa];
in[x]=++num;
if (son[x])
{
dfs_2(son[x],x);
for (int i=point[x];i;i=nxt[i])
if (v[i]!=fa && v[i]!=son[x]) dfs_2(v[i],x);
}
out[x]=num;
}
void updata(int now){sum[now]=sum[now<<1]+sum[now<<1|1];have[now]=have[now<<1]+have[now<<1|1];}
void pushdown(int now,int l,int r,int mid)
{
if (delta[now])
{
delta[now<<1]+=delta[now];
delta[now<<1|1]+=delta[now];
sum[now<<1]+=delta[now]*(mid-l+1);
sum[now<<1|1]+=delta[now]*(r-mid);
delta[now]=0;
}
if (bb[now]!=-1)
{
have[now<<1]=bb[now]*sum[now<<1]; have[now<<1|1]=bb[now]*sum[now<<1|1];
bb[now<<1]=bb[now<<1|1]=bb[now];
bb[now]=-1;
}
}
void change(int now,int l,int r,int lrange,int rrange,int v)
{
if (lrange<=l && rrange>=r) {sum[now]+=v*(r-l+1); delta[now]+=v; return;}
int mid=(l+r)>>1;pushdown(now,l,r,mid);
if (lrange<=mid) change(now<<1,l,mid,lrange,rrange,v);
if (rrange>mid) change(now<<1|1,mid+1,r,lrange,rrange,v);
updata(now);
}
void bj(int now,int l,int r,int lrange,int rrange,int co)
{
if (lrange<=l && rrange>=r) {have[now]=sum[now]*co; bb[now]=co; return;}
int mid=(l+r)>>1;pushdown(now,l,r,mid);
if (lrange<=mid) bj(now<<1,l,mid,lrange,rrange,co);
if (rrange>mid) bj(now<<1|1,mid+1,r,lrange,rrange,co);
updata(now);
}
void Que(int u,int v)
{
int f1=top[u],f2=top[v];
while (f1!=f2)
{
if (h[f1]<h[f2]) swap(f1,f2),swap(u,v);
bj(1,1,n,in[f1],in[u],1);
u=f[f1]; f1=top[u];
}
if (in[u]>in[v]) swap(u,v);
bj(1,1,n,in[u],in[v],1);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
addline(x,y);
}
dfs_1(1,0); dfs_2(1,0);
memset(bb,-1,sizeof(bb));
int q,k;scanf("%d",&q);
while(q--)
{
int id,x,v,y;scanf("%d",&id);
if (id==0) scanf("%d%d",&x,&v),change(1,1,n,in[x],out[x],v);
else
{
scanf("%d",&k);
while (k--) scanf("%d%d",&x,&y),Que(x,y);
printf("%d\n",have[1]&0x7fffffff);
bj(1,1,n,1,n,0);
}
}
}