zoukankan      html  css  js  c++  java
  • (后缀数组)Codeforces Round #434 (Div. 2) D.Polycarp's phone book

    B. Polycarp's phone book
    time limit per test
    4 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    There are n phone numbers in Polycarp's contacts on his phone. Each number is a 9-digit integer, starting with a digit different from 0. All the numbers are distinct.

    There is the latest version of Berdroid OS installed on Polycarp's phone. If some number is entered, is shows up all the numbers in the contacts for which there is a substring equal to the entered sequence of digits. For example, is there are three phone numbers in Polycarp's contacts: 123456789, 100000000 and 100123456, then:

    • if he enters 00 two numbers will show up: 100000000 and 100123456,
    • if he enters 123 two numbers will show up 123456789 and 100123456,
    • if he enters 01 there will be only one number 100123456.

    For each of the phone numbers in Polycarp's contacts, find the minimum in length sequence of digits such that if Polycarp enters this sequence, Berdroid shows this only phone number.

    Input

    The first line contains single integer n (1 ≤ n ≤ 70000) — the total number of phone contacts in Polycarp's contacts.

    The phone numbers follow, one in each line. Each number is a positive 9-digit integer starting with a digit from 1 to 9. All the numbers are distinct.

    Output

    Print exactly n lines: the i-th of them should contain the shortest non-empty sequence of digits, such that if Polycarp enters it, the Berdroid OS shows up only the i-th number from the contacts. If there are several such sequences, print any of them.

    Examples
    Input
    3
    123456789
    100000000
    100123456
    Output
    9
    000
    01
    Input
    4
    123456789
    193456789
    134567819
    934567891
    Output
    2
    193
    81
    91

    先将所有串连起来,中间用0——9以外的数字(且两两不同)隔开,求sa、height数组。

    扫一遍sa[i],对于每个sa[i],向前、向后找第一个出现的与其不是同一个串的位置,只需求这段height的RMQ,考虑到向左、向右最多走9步(实际上比这个少的多),直接用一个变量记录即可。

    与sa[i]起始的串相同的其他串的子串最大长度为 向左、向右走种上述RMQ的较大的一个。

    这样O(n)求完之后再扫一遍所有串,对于每个串,找其各个位置上述值的最小值(且需要符合题意,结尾+1不超过总长,因为最短的恰为公共长度+1),输出即可。

      1 #include <cstdio>
      2 #include <iostream>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <set>
      6 #include <map>
      7 #include <string>
      8 #include <cstring>
      9 #include <stack>
     10 #include <queue>
     11 #include <cmath>
     12 #include <ctime>
     13 #include <bitset>
     14 #include <utility>
     15 #include <assert.h>
     16 using namespace std;
     17 #define rank rankk
     18 #define mp make_pair
     19 #define pb push_back
     20 #define xo(a,b) ((b)&1?(a):0)
     21 #define tm tmp
     22 //#define LL ll
     23 typedef unsigned long long ull;
     24 typedef pair<int,int> pii;
     25 typedef long long ll;
     26 typedef pair<ll,int> pli;
     27 typedef pair<ll,ll> pll;
     28 const int INF=0x3f3f3f3f;
     29 const ll INFF=0x3f3f3f3f3f3f3f3fll;
     30 const int MAX=1e5+5;
     31 //const ll MAXN=2e8;
     32 //const int MAX_N=MAX;
     33 const ll MOD=1e9+7;
     34 //const long double pi=acos(-1.0);
     35 const long double eps=1e-9;
     36 int gcd(int a,int b){return b?gcd(b,a%b):a;}
     37 template<typename T>inline T abs(T a) {return a>0?a:-a;}
     38 template<class T> inline
     39 void read(T& num) {
     40     bool start=false,neg=false;
     41     char c;
     42     num=0;
     43     while((c=getchar())!=EOF) {
     44         if(c=='-') start=neg=true;
     45         else if(c>='0' && c<='9') {
     46             start=true;
     47             num=num*10+c-'0';
     48         } else if(start) break;
     49     }
     50     if(neg) num=-num;
     51 }
     52 inline ll powMM(ll a,ll b,ll M){
     53     ll ret=1;
     54     a%=M;
     55 //    b%=M;
     56     while (b){
     57         if (b&1) ret=ret*a%M;
     58         b>>=1;
     59         a=a*a%M;
     60     }
     61     return ret;
     62 }
     63 void open()
     64 {
     65 //    freopen("1009.in","r",stdin);
     66     freopen("out.txt","w",stdout);
     67 }
     68 
     69 const int MAXN=8e5;
     70 int t1[MAXN],t2[MAXN],c[MAXN];
     71 bool cmp(int *r,int a,int b,int l)
     72 {
     73     return r[a] == r[b] && r[a+l] == r[b+l];
     74 }
     75 void da(int str[],int sa[],int rank[],int height[],int n,int m)
     76 {
     77     str[n++]=0;
     78     int i, j, p, *x = t1, *y = t2;
     79     for(i = 0;i < m;i++)c[i] = 0;
     80     for(i = 0;i < n;i++)c[x[i] = str[i]]++;
     81     for(i = 1;i < m;i++)c[i] += c[i-1];
     82     for(i = n-1;i >= 0;i--)sa[--c[x[i]]] = i;
     83     for(j = 1;j <= n; j <<= 1)
     84     {
     85         p = 0;
     86         for(i = n-j; i < n; i++)y[p++] = i;
     87         for(i = 0; i < n; i++)if(sa[i] >= j)y[p++] = sa[i] - j;
     88         for(i = 0; i < m; i++)c[i] = 0;
     89         for(i = 0; i < n; i++)c[x[y[i]]]++;
     90         for(i = 1; i < m;i++)c[i] += c[i-1];
     91         for(i = n-1; i >= 0;i--)sa[--c[x[y[i]]]] = y[i];
     92         swap(x,y);
     93         p = 1; x[sa[0]] = 0;
     94         for(i = 1;i < n;i++)
     95             x[sa[i]] = cmp(y,sa[i-1],sa[i],j)?p-1:p++;
     96         if(p >= n)break;
     97         m = p;
     98     }
     99     int k = 0; n--;
    100     for(i = 0;i <= n;i++)rank[sa[i]] = i;
    101     for(i = 0;i < n;i++)
    102     {
    103         if(k)k--;
    104         j = sa[rank[i]-1]; while(str[i+k] == str[j+k])k++; height[rank[i]] = k;
    105     }
    106 }
    107 int rank[MAXN],height[MAXN];
    108 int st[MAXN];
    109 
    110 int sa[MAXN];
    111 int n,now,num[MAXN],lo,an,an1,an2;
    112 char str[MAXN];
    113 int main()
    114 {
    115     scanf("%d",&n);
    116     now=0;
    117     for(int i=1;i<=n;i++)
    118     {
    119         scanf("%s",str);
    120         for(int j=0;j<9;j++)
    121             st[now+j]=str[j]-'0'+1;
    122         st[now+9]=11+i;
    123         now+=10;
    124     }
    125     da(st,sa,rank,height,now,13+n);
    126     for(int i=1;i<=now;i++)
    127     {
    128         int who=sa[i]/10;
    129         int len=an1=an2=INF;
    130         int sts=i;
    131         while(sa[sts-1]/10==who)
    132         {
    133             an1=min(an1,height[sts]);--sts;
    134         }
    135         an1=min(an1,height[sts]);
    136         int en=i+1;
    137         while(sa[en]/10==who)
    138         {
    139             an2=min(an2,height[en]);
    140             ++en;
    141         }
    142         an2=min(an2,height[en]);
    143         if(an1==INF)an1=0;
    144         if(an2==INF)an2=0;
    145         len=max(an1,an2);
    146         num[sa[i]]=len;
    147     }
    148     now=0,an=9;
    149     for(int i=1;i<=n;i++)
    150     {
    151         lo=now;an=9;
    152         for(int j=0;j<9;j++)
    153         {
    154             if(num[now+j]<an&&num[now+j]+j<9)
    155             {
    156                 an=num[now+j];lo=now+j;
    157             }
    158         }
    159         for(int j=0;j<an+1;j++)
    160             printf("%d",st[lo+j]-1);
    161         printf("
    ");
    162         now+=10;
    163     }
    164     return 0;
    165 }
  • 相关阅读:
    ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍) 【转】
    一个建议,看看大家的意见。
    发现不错的文章,推!
    有个小问题,大家一起研究。
    逼不得已,这个我确实不会,昨办?
    MSN Message6.2 的小BUG
    在IE7浏览器中切换成以资源管理器方式
    手机罗盘(指南针)校准方法
    G13/ Wildfire S/A510e link2SD教程,干净清洁的安装程序到内存卡
    HTC G13电池怎么鉴别真伪
  • 原文地址:https://www.cnblogs.com/quintessence/p/7541902.html
Copyright © 2011-2022 走看看