zoukankan      html  css  js  c++  java
  • bzoj 1095 括号序列求两点距离

    大致题意: 给一棵树,每个节点最开始都是黑色,有两种操作,1.询问树中相距最远的一对黑点的距离 2.反转一个节点的颜色

    一种做法:

      建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n

      假如我们要询问AC间的距离,提取出中间的括号:[]],匹配消去后得到],其长度就是距离.

      现在我们要做的就是修改点的状态,并且动态维护答案.要用到一些求与绝对值相关的式子的技巧.

      1 /**************************************************************
      2     Problem: 1095
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:2176 ms
      7     Memory:55548 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #define min(a,b) ((a)<(b)?(a):(b))
     12 #define max(a,b) ((a)>(b)?(a):(b))
     13 #define N 100010
     14 #define M N<<1
     15 #define oo 0x3f3f3f3f
     16 #define fprintf(...)
     17  
     18 struct Node {
     19     int v[7], c, e, a;
     20     int lf, rg;
     21     Node *ls, *rs;
     22     void init( int type ) {
     23         if( type==0 ) {
     24             a = 0;
     25             e = false;
     26             c = 1;
     27             for( int t=0; t<7; t++ ) v[t]=0;
     28         } else if( type==-1 ) { //  (1,0)
     29             a = -1;
     30             e = true;
     31             c = 0;
     32             v[1] = v[3] = v[6] = v[2] = v[5] = 1;
     33             v[0] = v[4] = -1;
     34         } else {                //  (0,1)
     35             a = -1;
     36             e = true;
     37             c = 0;
     38             v[1] = v[3] = v[6] = v[0] = v[4] = 1;
     39             v[2] = v[5] = -1;
     40         }
     41     }
     42     void update() {
     43         e = ls->e && rs->e;
     44         v[5] = ls->v[5] + rs->v[5];
     45         v[4] = ls->v[4] + rs->v[4];
     46         v[6] = max( ls->v[6]+rs->v[4], ls->v[5]+rs->v[6] );
     47         if( !ls->e && !rs->e ) {
     48             v[0] = max( ls->v[0], ls->v[4]+rs->v[0] );
     49             v[1] = max( ls->v[1], max( ls->v[6]+rs->v[0], ls->v[5]+rs->v[1] ) );
     50             v[2] = max( rs->v[2], ls->v[2]+rs->v[5] );
     51             v[3] = max( rs->v[3], max( ls->v[3]+rs->v[4], ls->v[2]+rs->v[6] ) );
     52             a = max( max(ls->v[3]+rs->v[0],ls->v[2]+rs->v[1]), max(ls->a,rs->a) );
     53         } else if( !ls->e ) {
     54             v[0] = ls->v[0];
     55             v[1] = ls->v[1];
     56             v[2] = ls->v[2]+rs->v[5];
     57             v[3] = max( ls->v[3]+rs->v[4], ls->v[2]+rs->v[6] );
     58             a = ls->a;
     59         } else if( !rs->e ) {
     60             v[0] = ls->v[4]+rs->v[0];
     61             v[1] = max( ls->v[6]+rs->v[0], ls->v[5]+rs->v[1] );
     62             v[2] = rs->v[2];
     63             v[3] = rs->v[3];
     64             a = rs->a;
     65         } else {
     66             a = -1;
     67         }
     68     }
     69     void reverse( int pos ) {
     70         if( lf==rg ) {
     71             if( c ) {
     72                 c = 0;
     73                 a = -1;
     74                 e = true;
     75             } else {
     76                 c = 1;
     77                 a = 0;
     78                 e = false;
     79             }
     80             return;
     81         }
     82         int mid=(lf+rg)>>1;
     83         if( pos<=mid ) ls->reverse(pos);
     84         else rs->reverse(pos);
     85         update();
     86     }
     87 }pool[N*3*3], *tail=pool, *root;
     88  
     89 int n, m;
     90 int head[N], dest[M], next[M], etot;
     91 int dfn[N], sgn[N*3], fat[N], idc;
     92  
     93 void adde( int u, int v ) {
     94     etot++;
     95     next[etot] = head[u];
     96     dest[etot] = v;
     97     head[u] = etot;
     98 }
     99 void dfs( int u ) {
    100     sgn[++idc] = 1;
    101     dfn[u] = ++idc;
    102     fprintf( stderr, "[" );
    103     fprintf( stderr, "%d", u );
    104     for( int t=head[u]; t; t=next[t] ) {
    105         int v=dest[t];
    106         if( v==fat[u] ) continue;
    107         fat[v] = u;
    108         dfs(v);
    109     }
    110     sgn[++idc] = -1;
    111     fprintf( stderr, "]" );
    112 }
    113 Node *build( int lf, int rg ) {
    114     Node *nd = ++tail;
    115     nd->lf=lf, nd->rg=rg;
    116     if( lf==rg ) {
    117         nd->init( sgn[lf] );
    118     } else {
    119         int mid=(lf+rg)>>1;
    120         nd->ls = build( lf, mid );
    121         nd->rs = build( mid+1, rg );
    122         nd->update();
    123     }
    124     fprintf( stderr, "[%d,%d] a=%2d e=%d v[0~6] = %2d %2d %2d %2d %2d %2d %2d
    ",
    125             lf, rg, nd->a, nd->e, nd->v[0], nd->v[1], 
    126             nd->v[2], nd->v[3], nd->v[4], nd->v[5], nd->v[6] );
    127     return nd;
    128 }
    129 int main() {
    130     scanf( "%d", &n );
    131     for( int i=1,u,v; i<n; i++ ) {
    132         scanf( "%d%d", &u, &v );
    133         adde( u, v );
    134         adde( v, u );
    135     }
    136     for( int i=1; i<=n+n+n; i++ )
    137         fprintf( stderr, "%d", i%10 );
    138     fprintf( stderr, "
    " );
    139     fat[1] = 0;
    140     dfs(1);
    141     fprintf( stderr, "
    " );
    142     root = build( 1, idc );
    143     scanf( "%d", &m );
    144     for( int i=1,u; i<=m; i++ ) {
    145         char ch[10];
    146         scanf( "%s
    ", ch );
    147         if( ch[0]=='G' ) {
    148             printf( "%d
    ", root->a );
    149         } else {
    150             scanf( "%d", &u );
    151             root->reverse(dfn[u]);
    152         }
    153     }
    154 }
    View Code

    另一种做法大概是用点分,然后用堆维护最值.

  • 相关阅读:
    201671010432词频统计软件项目报告
    201671010432吴兰兰:实验三作业互评与改进报告
    快速通读《构建之法》后的疑问:
    读《构建之法》所提出的问题
    实验十四 团队项目评审&课程学习总结
    201671010437-王小倩-实验四附加实验
    201671010437+王小倩+《英文文本统计分析》结对项目报告
    201671010437 王小倩+词频统计软件项目报告
    201671010437 王小倩 + 实验三作业互评与改进报告
    201671010442 葸铃 实验十四 团队项目评审&课程学习总结
  • 原文地址:https://www.cnblogs.com/idy002/p/4579117.html
Copyright © 2011-2022 走看看