hdu 3183 st表

// 题意:从长度为 N 的字符串中删除 M 个字符,使得生成的新串的字典序最小

// 思路:反向构造

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 const int MAXN = 100010;
 4 int n;
 5 char ans[MAXN];
 6 int Min[MAXN][20], Max[MAXN][20];
 7 
 8 // 建st表, ans[MAXN], n读入之后调用
 9 void makeRmq()
10 {
11     int i, j, len;
12     for(i = 1; i <= n; ++i) {
13         Min[i][0] = Max[i][0] = i;
14     }
15 
16     int p, q;
17     for(j = 1; (len = 1 << j) <= n; ++j) {
18         for(i = 1; i + len - 1 <= n; ++i) {
19             p = Min[i][j - 1];
20             q = Min[i + (len >> 1)][j - 1];
21             if(ans[p] < ans[q] || (ans[p] == ans[q] && p < q)) {
22                 Min[i][j] = p;
23             }
24             else {
25                 Min[i][j] = q;
26             }
27 
28 //            p = Max[i][j - 1];
29 //            q = Max[i + (len >> 1)][j - 1];
30 //            if(ans[p] > ans[q] || (ans[p] == ans[q] && p < q)) {
31 //                Max[i][j] = p;
32 //            }
33 //            else {
34 //                Max[i][j] = q;
35 //            }
36         }
37     }
38 }
39 
40 // 取 [l, r] 的最小值和最大值放入 minValue 和 maxValue 中,且不需要初始化 minValue 和 maxValue
41 void ask(int l, int r, int &min_pos)
42 {
43     int pow_num, len, p, q;
44     pow_num = int(log(r - l + 1) / log(2));
45     len = 1 << pow_num;
46 
47     p = Min[l][pow_num];
48     q = Min[r - len + 1][pow_num];
49     if(ans[p] < ans[q] || (ans[p] == ans[q] && p < q)) {
50         min_pos = p;
51     }
52     else {
53         min_pos = q;
54     }
55 
56 //    p = Max[l][pow_num];
57 //    q = Max[r - len + 1][pow_num];
58 //    if(ans[p] > ans[q] || (ans[p] == ans[q] && p < q)) {
59 //        maxValue = ans[p];
60 //    }
61 //    else {
62 //        maxValue = ans[q];
63 //    }
64 }
65 char res[1010];
66 int tot;
67 int m;
68 
69 int main()
70 {
71     while (scanf("%s%d", ans + 1, &m) != EOF) {
72         tot = 0;
73         n = strlen(ans + 1);
74         makeRmq();
75         int cnt = n - m;
76         int min_pos;
77         int l = 1, r = m + 1;
78         while (cnt--) {
79             ask(l, r, min_pos);
80             res[tot++] = ans[min_pos];
81             l = min_pos + 1;
82             ++r;
83         }
84         res[tot] = '\0';
85         int index = 0;
86         while(index <= tot - 1 && res[index] == '0') {
87             ++index;
88         }
89         if(index == tot) {
90             printf("0\n");
91             continue;
92         }
93         printf("%s\n", res + index);
94     }
95 }

 

posted @ 2015-07-21 20:45  AC_Phoenix  阅读(191)  评论(0编辑  收藏  举报