• 北邮邀请赛J区间回文串


      1 //O(n)回文串
    2 # include <stdio.h>
    3 # include <algorithm>
    4 # include <iostream>
    5 # include <string>
    6 # include <cmath>
    7
    8 # define For(i,a) for(int (i)=0;i<(a);++(i))
    9 using namespace std;
    10 const int N=200100;
    11
    12 int lg[N<<1];
    13 char s[N],str[N<<1];
    14 int p[N<<1];
    15 int rmq[19][N<<1],n,up;
    16
    17 void pk()
    18 {
    19 int mx(0),id;
    20 rmq[0][0] = p[0] = 0;
    21 For(i,up)
    22 {
    23 if(mx > i)
    24 p[i] = min(p[id*2-i], mx-i);
    25 else
    26 p[i] = 1;
    27 while(str[i+p[i]] == str[i-p[i]])
    28 p[i]++;
    29 if(p[i] + i > mx)
    30 {
    31 mx = p[i] + i;
    32 id = i;
    33 }
    34 rmq[0][i] = p[i]-1;
    35 }
    36 }
    37 void pre_log()
    38 {
    39 int i,n;
    40 lg[0] = lg[1] = 0;
    41 for(i=1; i<N; i++)
    42 lg[i*2] = lg[i*2+1] = lg[i]+1;
    43 }
    44
    45 void pre_rmq(int rmq[][N<<1])
    46 {
    47 int i,k;
    48 int rn = (int)floor(log(2*n*2.0)/log(2.0));
    49 for(i=1;i<rn;i++)
    50 {
    51 k = 2*n + 2 - (1<<(i-1));
    52 For(j, k)
    53 rmq[i][j] = max(rmq[i-1][j], rmq[i-1][j+(1<<(i-1))]);
    54 }
    55 }
    56 int ask_rmq(int rmq[][N<<1],int a,int b) /// [a,b]闭区间
    57 {
    58 int rq = lg[b-a];
    59 return max(rmq[rq][a], rmq[rq][b+1-(1<<rq)]);
    60 }
    61 void read()
    62 {
    63 scanf("%s", s);
    64 n = strlen(s);
    65 str[0] = '$';
    66 str[1] = '#';
    67 For(i,n)
    68 {
    69 str[i*2 + 2] = s[i];
    70 str[i*2 + 3] = '#';
    71 }
    72 str[up = n*2 + 2] = 0;
    73 pk();
    74 pre_rmq(rmq);
    75 }
    76
    77 int doit()
    78 {
    79 int l,r,ans=0;
    80 int high,low=0,mid,gt;
    81 scanf("%d %d", &l, &r);
    82 high = r-l + 1;
    83 while(low <= high)
    84 {
    85 mid = (low + high) / 2;
    86 gt = ask_rmq(rmq, 2*l+mid-1, 2*r-mid+1);
    87 if(gt >= mid)
    88 {
    89 low = mid+1;
    90 ans = mid;
    91 }
    92 else
    93 high = mid-1;
    94 }
    95 return ans;
    96 }
    97
    98 int main()
    99 {
    100 pre_log();
    101 int T,_=0;
    102 int q,ans;
    103 scanf("%d",&T);
    104 while(_++ < T)
    105 {
    106 read();
    107 scanf("%d", &q);
    108 while(q--)
    109 {
    110 ans = doit();
    111 printf("%d\n", ans);
    112 }
    113 }
    114 return 0;
    115 }
  • 相关阅读:
    Spring 控制器层如何调用DAO层
    Spring 工程分层
    spring boot工程如何启用 热启动功能
    Spring 视图层如何显示验证消息提示
    Sping POJO中如何添加验证规则和验证消息提示
    Spirng 分层,增加数据访问对象层
    Spring A 标签链接使用
    Spring 控制器重定向
    课程详情页之后台
    课程详情页之前台
  • 原文地址:https://www.cnblogs.com/kirk/p/2114571.html
Copyright © 2020-2023  润新知