zoukankan      html  css  js  c++  java
  • P4211 [LNOI2014]LCA

    P4211 [LNOI2014]LCA

    链接

    分析:

      首先一种比较有趣的转化是,将所有点到1的路径上都+1,然后z到1的路径上的和,就是所有答案的deep的和。

      对于多次询问,要么考虑有把询问离线,省去每次询问的复杂度,多个一起处理,要么做到优化掉查询。

      这里发现求deep和的过程不能在省了,于是可以差分询问,枚举右端点,然后查询所有1到这个点的和。

      而第一步的操作可以树链剖分完成。(并且查询的是一个区间,这也保证了这样做可行)

      复杂度$O(nlog^2n)$

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    #define pa pair<int,int>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 100005, mod = 201314;
    struct Edge{ int to, nxt; } e[N << 1];
    int head[N], sum[N << 2], tag[N << 2], fa[N], siz[N], son[N], bel[N], xl[N], ans[N];
    int En, Index, n;
    vector< pa > Que[N];
    
    inline void add_edge(int u,int v) {
        ++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
    }
    inline void pushdown(int rt,int len) {
        sum[rt << 1] += (len - (len / 2)) * tag[rt];
        sum[rt << 1 | 1] += (len / 2) * tag[rt];
        tag[rt << 1] += tag[rt];
        tag[rt << 1 | 1] += tag[rt];
        tag[rt] = 0;
    }
    void update(int l,int r,int rt,int L,int R) {
        if (L <= l && r <= R) {
            tag[rt] ++; (sum[rt] += r - l + 1) %= mod; return ;
        }
        if (tag[rt]) pushdown(rt, r - l + 1);
        int mid = (l + r) >> 1;
        if (L <= mid) update(l, mid, rt << 1, L, R);
        if (R > mid) update(mid + 1, r, rt << 1 | 1, L, R);
        sum[rt] = (sum[rt << 1] + sum[rt << 1 | 1]) % mod;
    }
    int query(int l,int r,int rt,int L,int R) {
        if (L <= l && r <= R) return sum[rt];
        if (tag[rt]) pushdown(rt, r - l + 1);
        int mid = (l + r) >> 1, res = 0;
        if (L <= mid) res = (res + query(l, mid, rt << 1, L, R)) % mod;
        if (R > mid) res = (res + query(mid + 1, r, rt << 1 | 1, L, R)) % mod;
        return res;
    }
    void dfs1(int u) {
        siz[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            dfs1(v);
            siz[u] += siz[v];
            if (!son[u] || siz[son[u]] < siz[v]) son[u] = v;
        }
    }
    void dfs2(int u,int top) {
        bel[u] = top;
        xl[u] = ++Index;
        if (!son[u]) return ;
        dfs2(son[u], top);
        for (int i = head[u]; i; i = e[i].nxt) 
            if (e[i].to != son[u]) dfs2(e[i].to, e[i].to);
    }
    void add(int x) {
        while (x) {
            update(1, n, 1, xl[bel[x]], xl[x]);
            x = fa[bel[x]];
        }
    }
    int query(int x) {
        int ans = 0;
        while (x) {
            ans = (ans + query(1, n, 1, xl[bel[x]], xl[x])) % mod;
            x = fa[bel[x]];
        }
        return ans;
    }
    int main() {
        n = read();int m = read();
        for (int i = 2; i <= n; ++i) {
            fa[i] = read() + 1;
            add_edge(fa[i], i);
        }
        dfs1(1);
        dfs2(1, 1);
        for (int i = 1; i <= m; ++i) {
            int l = read() + 1, r = read() + 1, z = read() + 1;
            Que[r].push_back(pa(z, i));
            Que[l - 1].push_back(pa(z, -i));
        }
        for (int i = 1; i <= n; ++i) {
            add(i);
            for (int sz = Que[i].size(), j = 0; j < sz; ++j) {
                if (Que[i][j].second < 0) ans[-Que[i][j].second] -= query(Que[i][j].first);
                else ans[Que[i][j].second] += query(Que[i][j].first);
            }
        }
        for (int i = 1; i <= m; ++i) printf("%d
    ", (ans[i] + mod) % mod);
        return 0;
    }
  • 相关阅读:
    博客
    Windows Live Writer
    VirtualBox
    Linux dd
    Nginx与tomcat组合的简单使用
    压力测试之badboy和Jmeter的简单使用方法
    WebGIS中基于控制点库进行SHP数据坐标转换的一种查询优化策略
    浅谈利用SQLite存储离散瓦片的思路和实现方法
    常见ArcGIS操作(以10.0为例)
    (二十一)WebGIS中鹰眼的实现思路
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10347674.html
Copyright © 2011-2022 走看看