• luogu P3241 [HNOI2015]开店


    传送门

    (下面记年龄为(a_x))题目要求的是$$sum_{x=1}^{n} [a_xin [l,r]]dis(x,u)=sum_{x=1}^{n} [a_xin [l,r]]de_x+sum_{x=1}^{n} [a_xin [l,r]]de_u-2sum_{x=1}^{n}[a_xin [l,r]]*de_{lca(x,u)}$$

    式子的前两项可以利用前缀和比较方便的计算,问题是那个lca的深度和,考虑两个点的lca深度就是两个点到根路径交集长度,所以可以依次把满足条件的对应点 到根路径上的每个点 加上到父亲的边权,然后查询就是从一个点到根的权值和,这个可以用树链剖分+线段树实现

    然后考虑询问一个(a_i)([l,r])区间答案,可以看成询问([1,r])减去([1,l-1])所以可以套一个主席树,注意主席树要区间修改,要实现标记永久化

    #include<bits/stdc++.h>
    #define LL long long
    #define db double
    #define il inline
    #define re register
    
    using namespace std;
    const int N=150000+10,mod=1e9+7;
    il int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[N<<1],nt[N<<1],hd[N],tot=1;
    LL w[N<<1];
    il void add(int x,int y,int z)
    {
        ++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
        ++tot,to[tot]=x,nt[tot]=hd[y],w[tot]=z,hd[y]=tot;
    }
    int fa[N],fe[N],sz[N],hs[N],top[N],dfn[N],ti;
    LL de[N],s1[N],s2[N],ans;
    void dfs1(int x)
    {
        sz[x]=1;
        for(int i=hd[x];i;i=nt[i])
        {
            int y=to[i];
            if(y==fa[x]) continue;
            fa[y]=x,fe[y]=i,de[y]=de[x]+w[i],dfs1(y),sz[x]+=sz[y];
            hs[x]=sz[hs[x]]>sz[y]?hs[x]:y;
        }
    }
    void dfs2(int x,int ntp)
    {
        dfn[x]=++ti,s1[ti]=s1[ti-1]+w[fe[x]],top[x]=ntp;
        if(hs[x]) dfs2(hs[x],ntp);
        for(int i=hd[x];i;i=nt[i])
        {
            int y=to[i];
            if(y!=fa[x]&&y!=hs[x]) dfs2(y,y);
        }
    }
    int n,q,rt[N],tt,aa;
    struct sd
    {
        int a,i;
        bool operator < (const sd &bb) const {return a<bb.a;}
    }mm[N];
    struct node
    {
        int ch[2];
        LL s,t;
    }s[N*120];
    #define mid ((l+r)>>1)
    #define lc (s[o].ch[0])
    #define rc (s[o].ch[1])
    void bui(int &o,int l,int r)
    {
        o=++tt;
        if(l==r) return;
        bui(lc,l,mid),bui(rc,mid+1,r);
    }
    void modif(int &o,int l,int r,int ll,int rr)
    {
        s[++tt]=s[o],o=tt;
        if(l==ll&&r==rr) {++s[o].t;return;}
        s[o].s+=s1[rr]-s1[ll-1];
        if(ll<=mid) modif(lc,l,mid,ll,min(mid,rr));
        if(rr>mid) modif(rc,mid+1,r,max(mid+1,ll),rr);
    }
    LL quer(int o,int l,int r,int ll,int rr)
    {
        if(!o) return 0;
        LL an=s[o].t*(s1[rr]-s1[ll-1]);
        if(l==ll&&r==rr) return an+s[o].s;
        if(ll<=mid) an+=quer(lc,l,mid,ll,min(mid,rr));
        if(rr>mid) an+=quer(rc,mid+1,r,max(mid+1,ll),rr);
        return an;
    }
    #undef mid
    
    int main()
    {
        n=rd(),q=rd(),aa=rd();
        bui(rt[0],1,n);
        for(int i=1;i<=n;++i) mm[i]=(sd){rd(),i};
        sort(mm+1,mm+n+1);
        for(int i=1;i<n;++i)
        {
            int x=rd(),y=rd(),z=rd();
            add(x,y,z);
        }
        dfs1(1),dfs2(1,1);
        for(int i=1;i<=n;++i)
        {
            s2[i]=s2[i-1]+de[mm[i].i];
            rt[i]=rt[i-1];
            int x=mm[i].i;
            while(x)
            {
                modif(rt[i],1,n,dfn[top[x]],dfn[x]);
                x=fa[top[x]];
            }
        }
        while(q--)
        {
            int x=rd(),ll=(rd()+ans)%aa,rr=(rd()+ans)%aa;
            if(ll>rr) swap(ll,rr);
            int l=1,r=n,z=0;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(mm[mid].a>=ll) z=mid,r=mid-1;
                else l=mid+1;
            }
            ll=z;
            l=1,r=n,z=n;
            while(l<=r)
            {
                int mid=(l+r)>>1;
                if(mm[mid].a<=rr) z=mid,l=mid+1;
                else r=mid-1;
            }
            rr=z;
            ans=1ll*(rr-ll+1)*de[x]+s2[rr]-s2[ll-1];
            while(x)
            {
                ans-=2*(quer(rt[rr],1,n,dfn[top[x]],dfn[x])-quer(rt[ll-1],1,n,dfn[top[x]],dfn[x]));
                x=fa[top[x]];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    SysUtils.CompareText的注释
    获取进程列表及相关信息
    基于OpenCV的视频图像组态 (4) :劈裂动画效果
    基于OpenCV的视频图像组态 (3):常见PPT动画1
    基于OpenCV的视频图像组态 (2) :动画总体
    基于OpenCV的视频图像组态 (1) :时钟
    基于meanshift的手势跟踪与电脑鼠标控制(手势交互系统)
    小型便携式交互板安装设计
    小型便携式交互板安装设计
    乂文®便携触摸屏
  • 原文地址:https://www.cnblogs.com/smyjr/p/10438455.html
Copyright © 2020-2023  润新知