hdu 5431 AB String

来源:互联网 发布:云存储软件 编辑:程序博客网 时间:2024/05/24 05:35

AB String

 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
假定串仅含大写字符AABB。求没有在串SS中作为连续子串出现过的第KK小的串TT。比较TT按长度为第一关键字,字典序为第二关键字。
输入描述
第一行一个整数cases,表示数据组数。cases \leq 5cases5对于每一个组,第一行为串S(1<=|S|<=20000)S(1<=S<=20000)。第二行先给出询问次数times(1 \leq times \leq 10)times(1times10),接下来给出timestimes个正整数K(1 \leq K \leq 10^{9})K(1K109)
输出描述
对于每一个组,对每一个询问分别输出一行,表示串TT
输入样例
2A1 1AAABBA1 1
输出样例
BABA


其实答案长度不会超过31,所以可以31 * 20000取得所有子串(因为只有A, B, 所以可以转成整型),排序,然后二分答案就好了。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <tr1/unordered_set>using namespace std;using namespace std::tr1;#define LL __int64const int N = 7 * 1e6;const int LEN = 20000 + 5;LL a[N];int tot;char str[N];unordered_set<LL> myset;void init(int n) {myset.clear();tot = 0;}void deal(char str[]) {int len = strlen(str);init(len);for(int i = 1; i <= min(31, len); ++i) {LL num = 0;for(int j = 0; j < i; ++j) {LL add = 0;if(str[j] == 'B') add = 1;num = num * 2 + add;}LL h = (1LL << i) + num;if(myset.find(h) == myset.end()) {myset.insert(h);a[tot++] = h;}LL sub = (1LL << i);for(int j = i; j < len; ++j) {LL add = 0;if(str[j] == 'B') add = 1;num = num * 2 + add;if(str[j - i] == 'B') num -= sub;h = (1LL << i) + num;if(myset.find(h) == myset.end()) {myset.insert(h);a[tot++] = h;}}}}int ok(LL x, LL r) {LL p = lower_bound(a, a + tot, x) - a;LL tmp_r = x - 1 - p;if(a[p] == x) -- tmp_r;if(tmp_r < r) return -1;else {if(p < tot && a[p] == x) return 0;return 1;}}LL gao(int rank) {sort(a, a + tot);LL L = 1, R = (1LL << 33) - 1;LL ret = R;while(L < R) {LL mid = (L + R) >> 1;int flag = ok(mid, rank);if(flag == 0) {R = mid - 1;} else if(flag == 1) {R = mid;ret = min(ret, R);} else {L = mid + 1;}}if(ok(R, 1) == 1) ret = min(ret, R);return ret;}int main() {int T;scanf("%d", &T);while(T--) {scanf("%s", str);deal(str);int n;scanf("%d", &n);for(int i = 0; i < n; ++i) {int r;scanf("%d", &r);LL ans = gao(r);int len = 0;LL tmp_ans = ans;while(tmp_ans) {++len;tmp_ans /= 2;}ans -= (1LL << len);if(ans == 0) puts("A");else {for(int i = len - 2; i >= 0; --i) {if(ans & (1LL << i)) {printf("B");} else {printf("A");}}puts("");}}}return 0;}


0 0