• [HNOI 2015]开店


    题意:求“方便值”

    思路:树链剖分维护修改即可,似乎还有点分树的做法~

    #include<bits/stdc++.h>
    #define int long long
    #define debug(x) cout<<"debug:"<<x<<endl
    using namespace std;
    inline int read(){
        int q=0,f=1;char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-') f=-1;ch = getchar();
        }
        while(isdigit(ch)){
            q=q*10+ch-'0';ch=getchar();
        }
        return q*f;
    }
    const int maxn = 300010*2;
    const int inf = 0x3f3f3f3f;
    int n,m;
    int cnt;
    int idx;
    int rt[maxn];
    int size;
    int ans;
    
    int head[maxn];
    int nxt[maxn];
    int ver[maxn];
    int w[maxn];
    
    int siz[maxn];
    int fa[maxn];
    int top[maxn];
    int dfn[maxn];
    int Last[maxn];
    int root;
    
    inline void add(int u,int v,int wi){
        ver[++cnt] = v;
        nxt[cnt] = head[u];head[u] = cnt;
        w[cnt] = wi;
        return;
    }
    
    struct node
    {
        int v;
        int id;
    }a[maxn];
    
    inline bool operator < (node l,node r){
        return l.v == r.v ? l.id < r.id:l.v < r.v;
    }
    
    int dep[maxn];
    int Dep[maxn];
    #define travel(x) for(int i = head[x];i;i=nxt[i])
    inline void dfs1(int x,int f){
        siz[x] = 1;
        fa[x] = f;
        travel(x){
            int y = ver[i];
            if(y != f){
                dep[y] = dep[x] + w[i];
                Last[y] = w[i];
                dfs1(y,x);
                siz[x] += siz[y];
            }
        }
    }
    int E[maxn];
    inline void dfs2(int x,int f){
        dfn[x] = ++idx;
        E[dfn[x]] = Last[x];
        int mx = 0;
        int tmp = 0;
        travel(x){
            int y = ver[i];
            if(y != f && siz[y] > mx){
                tmp = y;
                mx = siz[y];
            }
        }
        if(!tmp) return;
        top[tmp] = top[x];
        dfs2(tmp,x);
        travel(x){
            int y  = ver[i];
            if(y != f && y != tmp){
                top[y] = y;
                dfs2(y,x);
            }
        }
    }
    const int maxm = 8e6+10;
    int ls[maxm];
    int rs[maxm];
    int sum[maxm];
    int tot[maxm];
    
    inline void modify(int l,int r,int L,int R,int &p,int v){
        p = ++size;
        ls[p] = ls[v];
        rs[p] = rs[v];
        sum[p] = sum[v];
        tot[p] = tot[v];
        if(l == L && r == R){
            ++tot[p];
            return;
        }
        sum[p] += E[r] - E[l - 1];
        int mid = (L + R) >> 1;
        if(r <= mid){
            modify(l,r,L,mid,ls[p],ls[v]);
        }
        else if(mid +1 <= l){
            modify(l,r,mid+1,R,rs[p],rs[v]);
        }
        else {
            modify(l,mid,L,mid,ls[p],ls[v]);
            modify(mid+1,r,mid+1,R,rs[p],rs[v]);
        }
    }
    
    inline int get_ans(int l,int r,int L,int R,int p){
        int res = (E[r] - E[l - 1])*tot[p];
        if(l == L && r == R){
            return res + sum[p];
        }
        int mid = (L + R) >> 1;
        if(r <= mid){
            return res + get_ans(l,r,L,mid,ls[p]);
        }
        else if(mid + 1 <= l){
            return res + get_ans(l,r,mid+1,R,rs[p]);
        }
        else{
            return res + get_ans(l,mid,L,mid,ls[p]) + get_ans(mid+1,r,mid+1,R,rs[p]);
        }
    }
    
    inline int get_rt(int p){
        while(p){
            modify(dfn[top[p]],dfn[p],1,n,root,root);
    
            p = fa[top[p]];
        }
        return root;
    }
    inline int query(int Rt,int p){
        int res = 0;
        while(p){
            res += get_ans(dfn[top[p]],dfn[p],1,n,Rt);
            //debug(res);
            p = fa[top[p]];
        }
        return res;
    }
    int A;
    inline void solve()
    {
        int x,y,z;
        n = read(),m = read(),A = read();
        for(int i = 1;i <= n; ++i){
            a[i].v = read();
            a[i].id = i;
        }
        sort(a+1,a+n+1);
        for(int i = 1;i < n; ++i){
            x = read(),y = read(),z = read();
            add(x,y,z);
            add(y,x,z);
        }
        dfs1(1,0),top[1] = 1;
        dfs2(1,0);
        for(int i = 1;i <= n; ++i){
            E[i] += E[i - 1];
            Dep[i] = Dep[i - 1] + dep[a[i].id];
            ///debug(Dep[i]);
        }
        for(int i = 1;i <= n; ++i){
            rt[i] = get_rt(a[i].id);
            //debug(rt[i]);
        }
    //  for(int i = 1;i <= n; ++i)
    //  {
    //      debug(a[i].v);
    //      debug(a[i].id);
    //  }
    //debug(ans);
        while(m--){
            z = read(),x = read(),y = read();
    //      debug(x);
    //      debug(y);
            x = (1ll * x + ans)%A;
            y = (1ll * y + ans) % A;
    //      debug(x);
    //      debug(y);
            if(x > y){
                swap(x,y);
            }
            x=lower_bound(a+1,a+1+n,(node){x,0})- a;
            y=upper_bound(a+1,a+1+n,(node){y,inf})-a-1;
    
            ans = (y - x + 1)*dep[z]+Dep[y] - Dep[x - 1];
            //debug(ans);
            ans -= 2ll*(query(rt[y],z) - query(rt[x - 1],z));
            //debug(ans);
            printf("%lld\n",ans);
        }
        return;
    }
    
    signed main(){solve();return 0;}
    
  • 相关阅读:
    android 请求网络异步载入
    A new Graph Game
    Android 高仿 频道管理----网易、今日头条、腾讯视频 (能够拖动的GridView)附源代码DEMO
    模块管理常规功能自己定义系统的设计与实现(16--模块数据的导出和打印[1])
    ganglia收集hbase的metrics
    ViewPager中View的复用
    PLY格式文件具体解释
    【RefactoringCode】The description of the refactoring book
    2.5星|《故事课2》:几个经典广告案例点评
    2星|叶檀《大破局》:2016年以来的财经时评文集,水平在平均线以下
  • 原文地址:https://www.cnblogs.com/akoasm/p/9419298.html
Copyright © 2020-2023  润新知