zoukankan      html  css  js  c++  java
  • HDU 5008 Boring String Problem

    题意:给定一个串长度<=1e5,将其所有的不同的字串按照字典序排序,然后q个询问,每次询问字典序第k小的的起始坐标,并且起始坐标尽量小。

    分析:

    一开始看错题意,没有意识到是求不同的字串中第k小的,果断不知道怎么做,感觉如果题目改成这样,似乎还有点难度,至少对我来说。

    好了,这个题目是考虑不同的字串,首先后缀数组处理,也就是讲后缀按照字典序排序,对于每个后缀开始的字串,如h[i],容易知道i和i-1的后缀的LCP长度为h[i]那么i中除开前h[i]个字串,之后的字串在i-1之前都是没有出现过的,而且字典序要比之前的大,这样的字串数目时len-sa[i]-h[i],那么对于每个i用val[i]表示,sum[i]表示前i项的val值之和,对于第k小的字串,找到一个sum[i]>k,然后判断一下sum[i-1]是不是==k,不是的话说明第k小的字串一定在后缀i的字串中出现过,并算出长度L。然后再确定其在整个字符串中出现的最左位置,L>h[i]显然成立,所以L只能在i之后的后缀的字串中出现,找到一个范围i~r,使得之间的h值>=L,然后RMQ求出最小的sa值,也就是字串出现的最左位置。

    话说暴力查找最左位置,竟然也能水过,而且速度还有快,测试数据里面肯定没有10000个a,每次询问第1小的字串这组数据。

    考虑相同的字串,询问第k小的怎么做?

    代码:

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <vector>
      4 #include <algorithm>
      5 #define inf 0x0f0f0f0f
      6 #define pb push_back
      7 #define bug(x) printf("line %d: >>>>>>>>>>>>>>>
    ", (x));
      8 #define in freopen("F:\code\data\data.txt", "r", stdin);
      9 #define out freopen("F:\code\data\data_out.txt", "w", stdout);
     10 
     11 #define SZ(x) ((int)x.size())
     12 #define lson rt<<1, l, m
     13 #define rson rt<<1|1, m+1, r
     14 #define fi first
     15 #define se second
     16 using namespace std;
     17 typedef long long LL;
     18 const int maxn = (int)1e5 + 100;
     19 int s[maxn], sa[maxn], t[maxn], t2[maxn], rk[maxn], h[maxn], c[maxn];
     20 int n, m;
     21 LL lans, rans;
     22 LL sum[maxn], val[maxn];
     23 
     24 void buildSa(int m)
     25 {
     26     int *x = t, *y = t2;
     27     for(int i = 0; i < m; i++) c[i] = 0;
     28     for(int i = 0; i < n; i++) c[x[i]=s[i]]++;
     29 
     30     for(int i = 1; i < m; i++) c[i] += c[i-1];
     31     for(int i = n-1; i >= 0; i--) sa[--c[x[i]]] = i;
     32 
     33     for(int k = 1; k <= n; k <<= 1)
     34     {
     35         int p = 0;
     36         for(int i = n-k; i < n; i++) y[p++] = i;
     37         for(int i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i]-k;
     38 
     39         for(int i = 0; i < m; i++) c[i] = 0;
     40         for(int i = 0; i < n; i++) c[x[i]]++;//
     41         for(int i = 1; i < m; i++) c[i] += c[i-1];
     42         for(int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];
     43 
     44         p = 1;
     45         swap(x, y);
     46         x[sa[0]] = 0;
     47 
     48         for(int i = 1; i < n; i++)
     49             x[sa[i]] = y[sa[i]] == y[sa[i-1]] && y[sa[i]+k] == y[sa[i-1]+k] ? p-1 : p++;
     50         m = p;
     51         if(p >= n)
     52             break;
     53     }
     54 }
     55 void getHeight()
     56 {
     57     int k = 0, j;
     58     h[0] = 0;
     59     for(int i = 0; i < n; i++) rk[sa[i]] = i;
     60     for(int i = 0; i < n; i++)
     61     {
     62         if(k) k--;
     63         if(rk[i] == 0)
     64             continue;
     65         j = sa[rk[i]-1];
     66         while(s[i+k] == s[j+k])
     67             k++;
     68         h[rk[i]] = k;
     69     }
     70 }
     71 int dp[maxn][20], mx[maxn][20];
     72 void rmqInit(int a[][20], int h[])
     73 {
     74     for(int i = 0; i < n; i++) a[i][0] = i;
     75     for(int k = 1; (1<<k) <= n; k++)
     76         for(int i = 0; i + (1<<k) <= n; i++)
     77             a[i][k] = h[a[i][k-1]] < h[a[i+(1<<(k-1))][k-1]] ? a[i][k-1] : a[i+(1<<(k-1))][k-1];
     78 }
     79 int RMQ(int l, int r, int a[][20], int h[])
     80 {
     81     if(l > r) swap(l, r);
     82     int k = 0;
     83     while((1<<(k+1)) < r-l+1) k++;
     84     return h[a[l][k]] <  h[a[r-(1<<k)+1][k]] ? a[l][k] : a[r-(1<<k)+1][k];
     85 }
     86 char str[maxn];
     87 int check(int l, int r)
     88 {
     89     return h[RMQ(l, r, dp, h)];
     90 }
     91 void solve(LL k)
     92 {
     93     if(k > sum[n-1])
     94     {
     95         lans = rans = 0;
     96         return;
     97     }
     98     int kk = upper_bound(sum+1, sum+n, k)-sum;
     99     if(sum[kk-1] == k)
    100         kk--;
    101     k -= sum[kk-1];
    102 
    103     int len = h[kk]+k;
    104     int x = sa[kk];
    105     if(kk+1 < n && h[kk+1] >= len)
    106     {
    107         int l = kk+1, r = n;
    108         while(r-l  > 1)
    109         {
    110             int mid = (l+r)>>1;
    111             if(check(mid, kk+1) >= len)
    112                 l = mid;
    113             else r = mid;
    114         }
    115         x = min(x, sa[RMQ(kk+1, l, mx, sa)]);
    116     }
    117     lans = x+1, rans = x+len;
    118 }
    119 int main()
    120 {
    121     
    122 
    123     while(scanf("%s", str) == 1)
    124     {
    125         n = 0;
    126         for(int i = 0; str[i]; i++)
    127             s[n++] = str[i]-'a'+1;
    128         s[n++] = 0;
    129         buildSa(30);
    130         getHeight();
    131         rmqInit(dp, h);
    132         rmqInit(mx, sa);
    133 //        bug(1)
    134         int q;
    135         lans = rans = 0;
    136         for(int i = 1; i < n; i++)
    137         {
    138             val[i] = n-1-sa[i]-h[i];
    139             sum[i] = sum[i-1] + val[i];
    140         }
    141         for(int t = scanf("%d", &q); t <= q; t++)
    142         {
    143             LL v;
    144             scanf("%I64d", &v);
    145             LL k = (lans^rans^v)+1;
    146             solve(k);
    147             printf("%I64d %I64d
    ", lans, rans);
    148         }
    149     }
    150     return 0;
    151 }
    View Code
  • 相关阅读:
    Records of Pytorch in Practice
    fast.ai Lesson 2: Deep Learning 2018
    fast.ai Lesson 1: Deep Learning 2018
    Learn You a PyTorch! (aka Introduction Into PyTorch)
    Deep RL Bootcamp Frontiers Lecture I: Recent Advances,
    Deep RL Bootcamp TAs Research Overview
    Deep RL Bootcamp Lecture 10B Inverse Reinforcement Learning
    Deep RL Bootcamp Lecture 9 Model-based Reinforcement
    Deep RL Bootcamp Lecture 8 Derivative Free Methods
    Deep RL Bootcamp Lecture 7: SVG, DDPG, and Stochastic Computation Graphs
  • 原文地址:https://www.cnblogs.com/rootial/p/3974072.html
Copyright © 2011-2022 走看看