残废代码库(自用

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define R register
int q[200007];
int n,m,r,mod;
//Segment tree
struct ahh{
    int l,r,v,tag;
}a[1600007];
void build(int ll,int rr,int i)
{
    a[i].l=ll;
    a[i].r=rr;
    if(ll==rr){a[i].v=q[ll]%mod;return;}
    int mid=(ll+rr)>>1;
    build(ll,mid,(i<<1));
    build(mid+1,rr,((i<<1)|1));
    a[i].v=(a[(i<<1)].v+a[((i<<1)|1)].v)%mod;
    return;
}
int ad;
void add(int ll,int rr,int i)
{
    if(ll==a[i].l&&rr==a[i].r){a[i].tag+=ad;return;}
    int mid=(a[i].l+a[i].r)>>1;
    if(rr<=mid)add(ll,rr,(i<<1));
    else if(ll>=mid+1)add(ll,rr,((i<<1)|1));
    else{add(ll,mid,(i<<1));add(mid+1,rr,((i<<1)|1));}
    return;
}
void pushtag(int i)
{
    if(!a[i].tag)return;
    if(a[i].l==a[i].r){a[i].v+=a[i].tag;a[i].v%=mod;a[i].tag=0;return;}
    a[(i<<1)].tag+=a[i].tag;
    a[((i<<1)|1)].tag+=a[i].tag;
    a[i].v+=a[i].tag;
    a[i].v%=mod;
    a[i].tag=0;
    return;
}
int find(int ll,int rr,int i)
{
    pushtag(i);
    if(a[i].l==ll&&a[i].r==rr)return a[i].v;
    int mid=(a[i].l+a[i].r)>>1;
    if(rr<=mid)return (find(ll,rr,(i<<1)))%mod;
    else if(ll>=mid+1)return (find(ll,rr,((i<<1)|1)))%mod;
    else return (find(ll,mid,(i<<1))+find(mid+1,rr,((i<<1)|1)))%mod;
}
//build tree
int s[100007];
struct emm{
    int e,f;
}b[200007];
int h[100007];
int cc=0;
void con(int x,int y)
{
    b[++cc].f=h[x];
    h[x]=cc;
    b[cc].e=y;
    return;
}
int fa[100007];
int siz[100007];
int mac[100007];
int z[100007];
int d[100007];
void dfs(int x)
{
    //int flag=0;
    siz[x]=1;
    for(int i=h[x];i;i=b[i].f)
    if(!d[b[i].e])
    {
      //  flag++;
        fa[b[i].e]=x;
        d[b[i].e]=d[x]+1;
        dfs(b[i].e);
        siz[x]+=siz[b[i].e];
        if(siz[b[i].e]>mac[x])
        {
            mac[x]=siz[b[i].e];
            z[x]=b[i].e;
        }
    }
    return;
}
int tot=0;
int in[100007];
int out[100007];
int top[100007];
void dfss(int x,int tp)
{
    q[++tot]=s[x];
    in[x]=tot;
    top[x]=tp;
    //if(!z[x]){q[++tot]=x;out[x]=tot;return;}
    if(z[x])dfss(z[x],tp);
    for(int i=h[x];i;i=b[i].f)
    if(b[i].e!=fa[x]&&b[i].e!=z[x])
    dfss(b[i].e,b[i].e);
    return;
}
//Qtree
//int top[100007];
int fitop(int x)
{
    if(z[fa[x]]==x)return top[x]=fitop(fa[x]);
    return top[x]=x;
}
void change(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(d[top[x]]>d[top[y]])swap(x,y);
        add(in[top[y]],in[y],1);y=fa[top[y]];
    }
    if(d[x]>d[y])swap(x,y);
    add(in[y],in[x],1);
    return;
}
int fin(int x,int y)
{
    int ans=0;
    while(top[x]!=top[y])
    {
        if(d[top[x]]>d[top[y]])swap(x,y);
        ans+=find(in[top[y]],in[y],1);
        ans%=mod;
        y=fa[top[y]];
    }
    if(d[x]>d[y])swap(x,y);
    ans+=find(in[y],in[x],1);
    return ans%mod;
}
//main
int main()
{
 //   freopen("a.in","r",stdin);
    scanf("%d%d%d%d",&n,&m,&r,&mod);
    for(R int i=1;i<=n;++i)
    {
        scanf("%d",&s[i]);
        s[i]%=mod;
    }
    for(R int i=1;i<=n-1;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        con(x,y);
        con(y,x);
    }
    fa[r]=1,d[r]=1;
    dfs(r);
    fa[r]=0;
    dfss(r,r);
    for(int i=1;i<=n;i++)cout<<in[i]<<endl;
    build(1,tot,1);
/*    for(R int i=1;i<=n;++i)
    if(!top[i])fitop(i);*/
    for(R int i=1;i<=m;++i)
    {
        int ch;
        scanf("%d",&ch);
        if(ch==1)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            ad=z;
            change(x,y);
        }
        if(ch==2)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d\n",(fin(x,y))%mod);
        }
        if(ch==3)
        {
            int x,z;
            scanf("%d%d",&x,&z);
            ad=z;
            add(in[x],out[x]-1,1);
        }
        if(ch==4)
        {
            int x;
            scanf("%d",&x);
            printf("%d\n",find(in[x],out[x]-1,1)%mod);
        }
    }
    return 0;
}
被大佬改过还是残废的树剖

猜你喜欢

转载自www.cnblogs.com/qwerta/p/9387501.html