zoukankan      html  css  js  c++  java
  • Aizu

    题意:给出一颗树,有两种操作:

    1. mark  u  标记结点u

    2.query  u  询问离u最近的且被标记的祖先结点是哪个

    让你输出所有询问的和。

    显然一个暴力的做法是每次都直接修改,然后查询的话就一个一个地向祖先查询,直到一个被标记过的点.

    让我们来优化一下这个暴力.

    类似于一个题https://www.luogu.com.cn/problem/P1653

    考虑反着搞,如果一个点的最早被标记时间比当前时间大或者根本没有被标记,那么这个点以后都不会用到了,可以被路径压缩掉.

    #include<cmath>
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<map>
    #include<queue>
    #include<set>
    #include<vector>
    #include<bitset>
    using namespace std;
    const int maxn=100005;
    int vis[maxn],fa[maxn],n,Q,cnt;
    long long ans;
    struct query
    {
        int t,id;
    }q[maxn];
    inline int read()
    {
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;
    }
    inline void write(long long a)
    {
        if(a<0)
        {
            char a='-',b='1';
            putchar(a);
            putchar(b);
        }
        else
        {
            if(a>=10)
                write(a/10);
            putchar(a%10+'0');
        }
    }
    int find(int id,int t)
    {
        return vis[id]<t?id:fa[id]=find(fa[id],t);
    }
    int main()
    {
        while(scanf("%d%d",&n,&Q)==2&&n&&Q)
        {
            for(int i=2;i<=n;++i)
                fa[i]=read(),vis[i]=1e9;
            ans=cnt=0;
            for(int i=1;i<=Q;++i)
            {
                char ch;
                cin>>ch;
                int x=read();
                if(ch=='Q')
                    q[++cnt].t=i,q[cnt].id=x;
                else
                    vis[x]=min(vis[x],i);
            }
            for(int i=cnt;i>=1;--i)
                ans+=find(q[i].id,q[i].t);
            write(ans);
            putchar('
    ');
        }
        return 0;
    }

    当然,这仍然是个暴力(虽然在Aizu上面过了),比如树退化成一条链且每一次都查询叶子节点而不修改,就可以被卡到n方.

    这里有一篇线段树维护的,大家可以看一下.

    https://www.cnblogs.com/zeroxf/p/6749091.html

    不要迫害Eriri啦 ~~~~(>_<)~~~~
  • 相关阅读:
    linux 命令——48 watch (转)
    linux 命令——47 iostat (转)
    linux 命令——46 vmstat(转)
    linux 命令——45 free(转)
    linux 命令——44 top (转)
    linux 命令——43 killall(转)
    linux 命令——42 kill (转)
    linux 命令——41 ps(转)
    linux 命令——40 wc (转)
    Java for LeetCode 068 Text Justification
  • 原文地址:https://www.cnblogs.com/520Enterprise/p/12012791.html
Copyright © 2011-2022 走看看