zoukankan      html  css  js  c++  java
  • 【HDOJ6223】Infinite Fraction Path(后缀数组,倍增)

    题意:

    给一个长度为n的字符串s[0..n-1],但i的后继不再是i+1,而是(i*i+1)%n,求所有长度为n的“子串”中,字典序最大的是谁

    n<=150000,s[i]=0..9

    思路:后缀数组

    因为前驱与后继的关系已经变化,就不能用下标直接加减

    i的后继是唯一的,i的前驱却不一定

    所以对于后继使用倍增,对于前驱每个位置暴力开队列存储,需要的时候再拿出来

    在判断的地方稍作修改

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 #include<bits/stdc++.h>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef unsigned int uint;
     15 typedef unsigned long long ull;
     16 typedef pair<int,int> PII;
     17 typedef vector<int> VI;
     18 #define fi first
     19 #define se second 
     20 #define MP make_pair
     21 #define N   310000
     22 #define MOD 1000000007
     23 #define eps 1e-8 
     24 #define pi acos(-1)
     25 queue<int> q[N];
     26 
     27 char ch[N];
     28 int n,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],Rank[N],
     29     f[N][19];
     30     
     31 
     32 int read()
     33 { 
     34    int v=0,f=1;
     35    char c=getchar();
     36    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     37    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     38    return v*f;
     39 }
     40 
     41 bool cmp(int *r,int a,int b,int l)
     42 {
     43     return r[a]==r[b]&&r[f[a][l]]==r[f[b][l]];
     44 //    return r[a]==r[b]&&r[a+l]==r[b+l]; 原来的写法 
     45 }
     46 
     47 void getsa(int *r,int *sa,int n,int m)
     48 {
     49 //    printf("
    ");
     50     int *x=wa,*y=wb,p;
     51     int k=0; 
     52     for(int i=0;i<n;i++) wc[x[i]=r[i]]++;
     53     for(int i=1;i<m;i++) wc[i]+=wc[i-1];
     54     for(int i=n-1;i>=0;i--) sa[--wc[x[i]]]=i;
     55     for(int j=1,p=1;p<n;j*=2,m=p)
     56     {
     57         p=0;
     58         /*for(i=n-j;i<n;i++) y[p++]=i;
     59         for(i=0;i<n;i++)
     60          if(sa[i]>=j) y[p++]=sa[i]-j;
     61         */ //默认后继为i+1应该是这个写法 
     62     
     63         for(int i=0;i<n;i++) q[f[i][k]].push(i);
     64         for(int i=0;i<n;i++)
     65          while(!q[sa[i]].empty())
     66          {
     67              y[p++]=q[sa[i]].front();
     68              q[sa[i]].pop();
     69          }
     70         for(int i=0;i<n;i++) wd[i]=x[y[i]];
     71         for(int i=0;i<m;i++) wc[i]=0;
     72         for(int i=0;i<n;i++) wc[wd[i]]++; 
     73         for(int i=1;i<m;i++) wc[i]+=wc[i-1];
     74         for(int i=n-1;i>=0;i--) sa[--wc[wd[i]]]=y[i];
     75         swap(x,y);
     76         p=1; x[sa[0]]=0;
     77         for(int i=1;i<n;i++) 
     78          x[sa[i]]=cmp(y,sa[i-1],sa[i],k)?p-1:p++;
     79         //printf("%d %d %d
    ",k,j,p);
     80         k++;
     81         if(j>n) break; //加上这句就A了,应该都是N很大,D[i]相同的数据吧,名次的并列很多 
     82     }
     83 }    
     84     
     85 
     86 
     87 int main()
     88 {
     89     freopen("hdoj6223.in","r",stdin);
     90     freopen("hdoj6223.out","w",stdout);
     91     int cas;
     92     scanf("%d",&cas);
     93     for(int v=1;v<=cas;v++)
     94     {
     95         printf("Case #%d: ",v);
     96         scanf("%d",&n);
     97          scanf("%s",ch);
     98          for(int i=0;i<n;i++) s[i]=ch[i]-'0'+1;
     99          for(int i=0;i<n;i++) f[i][0]=(1LL*i*i+1)%n;
    100      
    101         for(int j=1;j<=18;j++)
    102          for(int i=0;i<n;i++) f[i][j]=f[f[i][j-1]][j-1]; 
    103     
    104          
    105          
    106          s[n]=0;
    107          getsa(s,sa,n+1,20);
    108         int k=sa[n];
    109         for(int i=1;i<=n;i++)
    110         {
    111             printf("%c",ch[k]);
    112             k=f[k][0];
    113         }
    114         printf("
    ");
    115         for(int i=0;i<=max(20,n);i++)
    116         {
    117                s[i]=sa[i]=wa[i]=wb[i]=wc[i]=wd[i]=
    118               Rank[i]=0; 
    119         } 
    120     }
    121     return 0;
    122 }
    123      
  • 相关阅读:
    vue2.0 之 douban (二)创建自定义组件tabbar
    vue2.0 之 douban (一)框架搭建 及 整体布局
    react-navigation
    react-native modal
    javascript-使用el表达式获取后台传递的数据
    java Map
    java List集合
    javascript 自定义Map
    javascript Array(数组)
    ZOJ 3868 GCD Expectation (容斥+莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/myx12345/p/9735730.html
Copyright © 2011-2022 走看看