zoukankan      html  css  js  c++  java
  • HDU 4358 Boring counting 树状数组+思路

    研究了整整一天orz……直接上官方题解神思路

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <vector>
      5 #include <algorithm>
      6 
      7 using namespace std;
      8 
      9 const int MAXN = 100100;
     10 
     11 struct node
     12 {
     13     int v, next;
     14 };
     15 
     16 struct subTree
     17 {
     18     int st, ed;
     19 };
     20 
     21 struct Queryy
     22 {
     23     int i;
     24     int st, ed;
     25 };
     26 
     27 int N, K, Q;
     28 int EdgeN, TimeFlag;
     29 node D[MAXN];   //树节点
     30 int C[MAXN];    //树状数组
     31 int head[MAXN];
     32 subTree tree[MAXN];   //子树映射成线性序列之后对应的区间
     33 Queryy qry[MAXN];     //查询信息
     34 int weight[MAXN], addr[MAXN];
     35 int ans[MAXN];
     36 vector<int> pos[MAXN];
     37 
     38 void AddEdge( int u, int v )
     39 {
     40     D[EdgeN].v = v;
     41     D[EdgeN].next = head[u];
     42     head[u] = EdgeN++;
     43     return;
     44 }
     45 
     46 void DFS( int cur )                    //树形结构转线性结构
     47 {
     48     tree[ cur ].st = ++TimeFlag;
     49     addr[ TimeFlag ] = weight[ cur ];
     50     for ( int i = head[cur]; i != -1; i = D[i].next )
     51         DFS( D[i].v );
     52     tree[cur].ed = TimeFlag;
     53     return;
     54 }
     55 
     56 int lowbit( int x )
     57 {
     58     return (-x) & x;
     59 }
     60 
     61 void add( int x, int val )
     62 {
     63     while ( x <= N )
     64     {
     65         C[x] += val;
     66         x += lowbit(x);
     67     }
     68     return;
     69 }
     70 
     71 int query( int x )
     72 {
     73     int res = 0;
     74     while ( x > 0 )
     75     {
     76         res += C[x];
     77         x -= lowbit(x);
     78     }
     79     return res;
     80 }
     81 
     82 bool cmp( int a, int b )
     83 {
     84     return weight[a] < weight[b];
     85 }
     86 
     87 void init()    //将weight离散化
     88 {
     89     sort( addr + 1, addr + N + 1, cmp );
     90 
     91     int cnt = 0, pre = -1;
     92     for ( int i = 1; i <= N; ++i )
     93     {
     94         if ( weight[ addr[i] ] != pre )
     95             pre = weight[ addr[i] ], weight[ addr[i] ] = ++cnt;
     96         else weight[ addr[i] ] = cnt;
     97     }
     98     return;
     99 }
    100 
    101 bool cmp2( Queryy a, Queryy b )
    102 {
    103     return a.ed < b.ed;
    104 }
    105 
    106 void solved()
    107 {
    108     for ( int i = 0; i <= N; ++i ) pos[i].clear();
    109 
    110     sort( qry, qry + Q, cmp2 );
    111     int cur = 0;
    112     for ( int i = 1; i <= N; ++i )
    113     {
    114         int val = addr[i];
    115         pos[val].push_back(i);
    116         int sz = pos[val].size();
    117         if ( sz == K )
    118             add( pos[val][ sz - K ], 1 );
    119         else if ( sz > K )
    120         {
    121             add( pos[val][ sz - K ], 1 );
    122             add( pos[val][ sz - K - 1 ], -2 );
    123         }
    124         //printf( "ed = %d
    ", qry[cur].ed );
    125         while ( cur < Q && qry[cur].ed == i )
    126         {
    127             int id = qry[cur].i;
    128             ans[id] = query( qry[cur].ed ) - query( qry[cur].st - 1 );
    129           //  printf("ans[%d] = %d
    ", id, ans[id] );
    130             ++cur;
    131         }
    132     }
    133     return;
    134 }
    135 
    136 int main()
    137 {
    138     int T, cas = 0;
    139     scanf( "%d", &T );
    140     while ( T-- )
    141     {
    142         memset( head, -1, sizeof( head ) );
    143         memset( C, 0, sizeof(C) );
    144 
    145         scanf( "%d%d", &N, &K );
    146         for ( int i = 1; i <= N; ++i )
    147         {
    148             scanf( "%d", &weight[i] );
    149             addr[i] = i;
    150         }
    151         init();
    152 
    153         EdgeN = 0;
    154 
    155         for ( int i = 1; i < N; ++i )      //建树
    156         {
    157             int u, v;
    158             scanf( "%d%d", &u, &v );
    159             AddEdge( u, v );
    160         }
    161 
    162         TimeFlag = 0;
    163         DFS(1);                           //树形结构转线性结构
    164 
    165         scanf( "%d", &Q );
    166         printf( "Case #%d:
    ", ++cas );
    167         for ( int i = 0; i < Q; ++i )
    168         {
    169             int u;
    170             scanf( "%d", &u );
    171             qry[i].i = i;
    172             qry[i].st = tree[u].st;
    173             qry[i].ed = tree[u].ed;
    174            // printf( "%d %d
    ", qry[i].st, qry[i].ed );
    175         }
    176         solved();
    177         for ( int i = 0; i < Q; ++i )
    178             printf( "%d
    ", ans[i] );
    179 
    180         if ( T ) puts("");
    181     }
    182     return 0;
    183 }
  • 相关阅读:
    206.反转链表
    gprof
    Java【Stream流、方法引用】学习笔记
    Java【函数式接口(Supplier、Comsumer、Predicate、Function)】学习笔记
    Python exec 内置语句
    Python sorted() 函数
    Python oct() 函数
    Python id() 函数
    Python dir() 函数
    软件测试的方法
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3193499.html
Copyright © 2011-2022 走看看