zoukankan      html  css  js  c++  java
  • bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095

    点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGold/p/8463436.html

    线段树维护括号序列

    对树进行dfs,入栈时加一个左括号,出栈时加一个右括号,那么书上两点间的距离=括号序列两点间不匹配括号数

    例:

    树1--2--3,2为根

    括号序列为 (2(3)(1))

    2和1的距离 为 ()( = 1, 3和1的距离为 )( =2

    具体怎么维护不想写了,去看曹钦翔的冬令营讲稿《数据结构的提炼与压缩》(p29、30)吧

    #include<cstdio>
    #include<iostream>
    
    #define N 100001
    
    using namespace std;
    
    int front[N],nxt[N<<1],to[N<<1],tot;
    
    int id[N];
    int num[N*3];
    
    bool light[N];
    
    #define max(a,b) ((a)>(b) ? (a) : (b))
    
    struct node
    {
        int a,b,dis;
        int right_plus,right_minus,left_plus,left_minus;
    
        void get_val(int x)
        {
            a=b=0;
            right_plus=right_minus=left_plus=left_minus=dis=-1e7;
            if(num[x]==-1) b=1;
            else if(num[x]==-2) a=1;
            else if(!light[num[x]]) right_plus=right_minus=left_plus=left_minus=dis=0;
        }
    
        node operator + (node p)
        {
            node k;
            k.a=max(a,a+p.a-b);
            k.b=max(p.b,p.b+b-p.a);
            k.dis=max(max(dis,p.dis),max(right_plus+p.left_minus,right_minus+p.left_plus));
            int A=a,B=b,C=p.a,D=p.b;
            k.right_plus=max(p.right_plus,max(right_plus+D-C,right_minus+D+C));
            k.right_minus=max(p.right_minus,right_minus+C-D);
            k.left_plus=max(left_plus,max(A+B+p.left_minus,A-B+p.left_plus));
            k.left_minus=max(left_minus,B-A+p.left_minus);
            return k;
        }
    
    }tr[N*3<<2];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    
    void dfs(int x,int fa)
    {
        num[++tot]=-1;
        id[num[++tot]=x]=tot;
        for(int i=front[x];i;i=nxt[i])
            if(to[i]!=fa) dfs(to[i],x);
        num[++tot]=-2;
    }
    
    void build(int k,int l,int r)
    {
        if(l==r)
        {
            tr[k].get_val(l);
            return;
        }
        int mid=l+r>>1;
        build(k<<1,l,mid);
        build(k<<1|1,mid+1,r);
        tr[k]=tr[k<<1]+tr[k<<1|1];
    }
    
    void change(int k,int l,int r,int pos)
    {
        if(l==r)
        {
            tr[k].get_val(l);
            return;
        }
        int mid=l+r>>1;
        if(pos<=mid) change(k<<1,l,mid,pos);
        else change(k<<1|1,mid+1,r,pos);
        tr[k]=tr[k<<1]+tr[k<<1|1];
    }
    
    int main()
    {
        int n,u,v;
        read(n);
        for(int i=1;i<n;++i)
        {
            read(u); read(v);
            add(u,v);
        }
        tot=0;
        dfs(1,0);
        build(1,1,tot);
        int m; char s[3];
        read(m);
        int cnt=n;
        while(m--)
        {
            scanf("%s",s);
            if(s[0]=='G') 
            {
                if(cnt<=1) printf("%d
    ",cnt-1);
                else  printf("%d
    ",tr[1].dis);
            }
            else 
            {
                read(u);
                if(light[u]) cnt++;
                else cnt--;
                light[u]^=1;
                change(1,1,tot,id[u]);
            }
        }
        return 0;
    }
  • 相关阅读:
    输入url后的加载过程~
    编写一个方法,求字符串长度~~~
    闭包 什么是闭包 为什么用闭包~~
    作用域链的理解~~
    谈谈javascript的基本规范~~~~
    html中datalist 是什么??????
    elementui中el-input联想搜索框
    js中数组对象去重的方法
    vue视频截图第一帧demo
    styled-components的基本使用
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8476935.html
Copyright © 2011-2022 走看看