zoukankan      html  css  js  c++  java
  • 【HDOJ】4601 Letter Tree

    挺有意思的一道题,思路肯定是将图转化为Trie树,这样可以求得字典序。
    然后,按照trie的层次求解。一直wa的原因在于将树转化为线性数据结构时要从原树遍历,从trie遍历就会wa。不同结点可能映射为trie上的同一结点,如
    1->2 (a) 1->3(a) 2->4(b), 这是trie的结构是RT->a->b。然而,从结点3不能找到权重为b的路径。
    用RMQ求满足边界的rank最大值,通过sa找到该最大值对应的trie上的根。从而求解。

      1 /* 4601 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <algorithm>
     12 #include <cstdio>
     13 #include <cmath>
     14 #include <ctime>
     15 #include <cstring>
     16 #include <climits>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <functional>
     20 #include <iterator>
     21 #include <iomanip>
     22 using namespace std;
     23 //#pragma comment(linker,"/STACK:102400000,1024000")
     24 
     25 #define sti                set<int>
     26 #define stpii            set<pair<int, int> >
     27 #define mpii            map<int,int>
     28 #define vi                vector<int>
     29 #define pii                pair<int,int>
     30 #define vpii            vector<pair<int,int> >
     31 #define rep(i, a, n)     for (int i=a;i<n;++i)
     32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     33 #define clr                clear
     34 #define pb                 push_back
     35 #define mp                 make_pair
     36 #define fir                first
     37 #define sec                second
     38 #define all(x)             (x).begin(),(x).end()
     39 #define SZ(x)             ((int)(x).size())
     40 #define lson            l, mid, rt<<1
     41 #define rson            mid+1, r, rt<<1|1
     42 // #define DEBUG 
     43 
     44 typedef struct {
     45     int u, v, w;
     46     int nxt;
     47 } edge_t;
     48 
     49 typedef struct ques_t {
     50     int u, m, id;
     51 
     52     ques_t() {}
     53     friend bool operator< (const ques_t& a, const ques_t& b) {
     54         if (a.m == b.m)
     55             return a.id < b.id;
     56         return a.m < b.m;
     57     }
     58 
     59 } ques_t;
     60 
     61 const int mod = 1e9+7;
     62 const int maxn = 1e5+5;
     63 const int maxv = maxn;
     64 const int maxe = maxv * 2;
     65 int head[maxv], m;
     66 edge_t E[maxe];
     67 int nxt[maxn][26], l;
     68 int Pos[maxv], Rank[maxv], sa[maxv];
     69 __int64 Base[maxn];
     70 __int64 Val[maxn];
     71 int deep[maxv];
     72 int fr[maxv], to[maxv];
     73 int dfs_clock;
     74 vi layer[maxn];
     75 int maxd;
     76 int n, qn, q;
     77 ques_t Qu[maxn];
     78 int ans[maxn];
     79 int dp[17][maxn];
     80 int D[maxn];
     81 
     82 void Init() {
     83     Base[0] = 1;
     84     rep(i, 1, maxn)
     85         Base[i] = Base[i-1] * 26 % mod;
     86 }
     87 
     88 void init() {
     89     memset(head, -1, sizeof(head));
     90     m = 0;
     91     memset(nxt[1], 0, sizeof(nxt[1]));
     92     l = 1;
     93     dfs_clock = 0;
     94     maxd = 0;
     95     rep(i, 0, n+1)
     96         layer[i].clr();
     97 }
     98 
     99 int newNode() {
    100     ++l;
    101     memset(nxt[l], 0, sizeof(nxt[l]));
    102     Val[l] = 0;
    103     return l;
    104 }
    105 
    106 void addEdge(int u, int v, int w) {
    107     E[m].v = v;
    108     E[m].w = w;
    109     E[m].nxt = head[u];
    110     head[u] = m++;
    111 
    112     E[m].v = u;
    113     E[m].w = w;
    114     E[m].nxt = head[v];
    115     head[v] = m++;
    116 }
    117 
    118 void Build_Trie(int u, int fa, int rt) {
    119     int v, k, p;
    120 
    121     Pos[u] = rt;
    122     for (k=head[u]; k!=-1; k=E[k].nxt) {
    123         v = E[k].v;
    124         if (v == fa)
    125             continue;
    126 
    127         int id = E[k].w;
    128         p = nxt[rt][id];
    129         if (!p)
    130             p = nxt[rt][id] = newNode();
    131         Build_Trie(v, u, p);
    132     }
    133 }
    134 
    135 void Mark_Rank(int rt, int d) {
    136     int p;
    137 
    138     Rank[rt] = ++dfs_clock;
    139     sa[dfs_clock] = rt;
    140     rep(i, 0, 26) {
    141         p = nxt[rt][i];
    142         if (p) {
    143             Val[p] = (Val[rt]*26 + i) % mod;
    144             Mark_Rank(p, d+1);
    145         }
    146     }
    147 }
    148 
    149 void calDepth(int u, int fa, int rt) {
    150     int v, k, p;
    151     
    152     D[++dfs_clock] = Rank[rt];
    153     fr[u] = dfs_clock + 1;
    154     maxd = max(deep[u], maxd);
    155     layer[deep[u]].pb(dfs_clock);
    156     for (k=head[u]; k!=-1; k=E[k].nxt) {
    157         v = E[k].v;
    158         if (v == fa)
    159             continue;
    160         deep[v] = deep[u] + 1;
    161         p = nxt[rt][E[k].w];
    162         calDepth(v, u, p);
    163     }
    164     to[u] = dfs_clock;
    165 }
    166 
    167 void init_RMQ(int d, int n) {
    168     int i, j;
    169 
    170     for (i=0; i<n; ++i)
    171         dp[0][i] = D[layer[d][i]];
    172     for (j=1; (1<<j)<=n; ++j)
    173         for (i=0; i+(1<<j)-1<n; ++i)
    174             dp[j][i] = max(dp[j-1][i], dp[j-1][i+(1<<(j-1))]);
    175 }
    176 
    177 int RMQ(int l, int r) {
    178     if (l > r)
    179         swap(l, r);
    180 
    181     int k = 0;
    182 
    183     while ((1<<(k+1)) <= r-l+1)
    184         ++k;
    185 
    186     return max(dp[k][l], dp[k][r-(1<<k)+1]);
    187 }
    188 
    189 int calc(int qid, int d) {
    190     int u = Qu[qid].u;
    191     int rt = Pos[u];
    192     int b = fr[u];
    193     int e = to[u];
    194     int l = lower_bound(all(layer[d]), b) - layer[d].begin();
    195     int r = upper_bound(all(layer[d]), e) - layer[d].begin();
    196     --r;
    197     
    198     if (l > r)
    199         return -1;
    200 
    201     int mxrank = RMQ(l, r);
    202     int mxrt = sa[mxrank];
    203     int delta = d - deep[u];
    204     int ret = (Val[mxrt] - Val[rt] * Base[delta] % mod + mod) % mod;
    205 
    206     return ret;
    207 }
    208 
    209 void solve() {
    210     Build_Trie(1, 0, 1);
    211     Mark_Rank(1, 0);
    212     dfs_clock = 0;
    213     deep[1] = 0;
    214     calDepth(1, 0, 1);
    215     
    216     scanf("%d", &q);
    217     qn = 0;
    218     rep(i, 0, q) {
    219         scanf("%d %d", &Qu[qn].u, &Qu[qn].m);
    220         int deepu = deep[Qu[qn].u];
    221         if (Qu[qn].m == 0) {
    222             ans[i] = 0;
    223         } else if (deepu+Qu[qn].m > maxd) {
    224             ans[i] = -1;
    225         } else {
    226             Qu[qn].m += deepu;
    227             Qu[qn].id = i;
    228             ++qn;
    229         }
    230     }
    231     
    232     if (qn) {
    233         sort(Qu, Qu+qn);
    234         int j = 0;
    235         rep(i, 0, maxd+1) {
    236             if (i < Qu[j].m)
    237                 continue;    
    238             int sz = SZ(layer[i]);
    239             init_RMQ(i, sz);
    240             while (j<=qn && Qu[j].m==i) {
    241                 int id = Qu[j].id;
    242                 ans[id] = calc(j, i);
    243                 ++j;
    244             }
    245             if (j == qn)
    246                 break;
    247         }
    248     }
    249 
    250     rep(i, 0, q) {
    251         if (ans[i] == -1)
    252             puts("IMPOSSIBLE");
    253         else
    254             printf("%d
    ", ans[i]);
    255     }
    256 }
    257 
    258 int main() {
    259     ios::sync_with_stdio(false);
    260     #ifndef ONLINE_JUDGE
    261         freopen("data.in", "r", stdin);
    262         freopen("data.out", "w", stdout);
    263     #endif
    264 
    265     int t;
    266     int u, v;
    267     char ws[4];
    268 
    269     Init();
    270     scanf("%d", &t);
    271     while (t--) {
    272         scanf("%d", &n);
    273         init();
    274         rep(i, 1, n) {
    275             scanf("%d %d %s", &u, &v, ws);
    276             addEdge(u, v, ws[0]-'a');
    277         }
    278         solve();
    279     }
    280 
    281     #ifndef ONLINE_JUDGE
    282         printf("time = %d.
    ", (int)clock());
    283     #endif
    284 
    285     return 0;
    286 }

     数据发生器。

     1 from random import randint, shuffle
     2 import shutil
     3 import string
     4 
     5 
     6 def GenDataIn():
     7     with open("data.in", "w") as fout:
     8         t = 10
     9         bound = 10**3
    10         lc = list(string.lowercase)
    11         fout.write("%d
    " % (t))
    12         for tt in xrange(t):
    13             n = randint(300, 500)
    14             fout.write("%d
    " % (n))
    15             ust = [1]
    16             vst = range(2, n+1)
    17             for i in xrange(1, n):
    18                 uid = randint(0, len(ust)-1)
    19                 vid = randint(0, len(vst)-1)
    20                 u = ust[uid]
    21                 v = vst[vid]
    22                 ust.append(v)
    23                 vst.remove(v)
    24                 idx = randint(0, 25)
    25                 c = lc[idx]
    26                 fout.write("%d %d %s
    " % (u, v, c))
    27             q = randint(400, 600)
    28             fout.write("%d
    " % (q))
    29             for i in xrange(q):
    30                 u = randint(1, n+1)
    31                 m = randint(0, 10)
    32                 fout.write("%d %d
    " % (u, m))
    33                 
    34                 
    35 def MovDataIn():
    36     desFileName = "F:eclipse_prjworkspacehdojdata.in"
    37     shutil.copyfile("data.in", desFileName)
    38 
    39     
    40 if __name__ == "__main__":
    41     GenDataIn()
    42     MovDataIn()
  • 相关阅读:
    十年经验手把手教你选购翡翠
    眼睛视力
    玻璃
    前端小技巧
    儿童牙齿矫正
    MySQL的JDBC驱动源码解析
    书海杂谈
    电子设备
    股市国家队
    影视
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5184152.html
Copyright © 2011-2022 走看看