zoukankan      html  css  js  c++  java
  • 校内模拟赛 SovietPower Play With Amstar

    SovietPower Play With Amstar

    题意:

      一棵二叉树,每次询问一条路径上的路径和,初始每个点有一个权值1,询问后权值变为0。$n leq 10^7,mleq10^6$

    分析:

      首先树链剖分+线段树可做,$O(mlog^2)$,复杂度太大。

      然后并查集缩点,树剖求lca,$O(n+mlogn)$。可以被卡一个subtask。

      考虑我们并查集的过程中是不断往上跳,跳到相等时结束,这个点可能是lca,也可能不是,需要判断一下,考虑优化这个判断。

      二叉树的前序遍历有一个性质:两个点的lca在他们中间。于是按照这个性质就可以$O(n+m)$了。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    #include<cmath>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<bitset>
    #define Swap(l, r) l ^= r, r ^= l, l ^= r
    #define fore(i, u, v) for (int i = head[u], v = e[i].to; i; i = e[i].nxt, v = e[i].to) 
    using namespace std;
    typedef long long LL;
    
    char buf[10000000], *p1 = buf, *p2 = buf;
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,10000000,stdin),p1==p2)?EOF:*p1++)
    inline int read() {
        int x=0,f=1;char ch=nc();for(;!isdigit(ch);ch=nc())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=nc())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 10000005;
    int ls[N], rs[N], fa[N], pos[N], f[N], dep[N];
    int Root, Index;
    
    inline void add_edge(int u,int v) {
        if (v == Root || u == 0) return ;
        if(!ls[u]) ls[u] = v;
        else rs[u] = v; 
    }
    void dfs(int u) {
        if (!u) return ;
        dep[u] = dep[fa[u]] + 1;
        dfs(ls[u]);
        pos[u] = ++Index;
        dfs(rs[u]);
    }
    int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }
    int solve(int u,int v) {
        int ans = 0, l = pos[u], r = pos[v]; l > r ? Swap(l, r) : l;
        u = find(u), v = find(v);
        while (u != v) ans ++, dep[u] > dep[v] ? u = f[u] = find(fa[u]) : v = f[v] = find(fa[v]);
        if (pos[u] >= l && pos[u] <= r) ans ++, f[u] = find(fa[u]), u = find(u);
        return ans;
    }
    int main() {
        read();int opt = read(), n = read(), m = read(); Root = read();
        for (int i = 1; i <= n; ++i) fa[i] = read(), add_edge(fa[i], i);
        dfs(Root);
        for (int i = 1; i <= n; ++i) f[i] = i;
        int lastans = 0, u, v;
        while (m --) {
            u = read(), v = read();
            u = (u ^ (lastans * opt)) % n + 1, v = (v ^ (lastans * opt)) % n + 1;
            lastans = solve(u, v);
            printf("%d
    ", lastans);
        }
        return 0;
    }
  • 相关阅读:
    springMVC
    自动装配
    HTTP Status 500
    this compilation unit is not on the build of a java project
    Struct2提交表单数据到Acion
    ResultMap
    MyEclipse 代码自动提示
    xe mysql
    java Study 基础 1
    InterfaceConnect
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10650897.html
Copyright © 2011-2022 走看看