• Hdu-6230 2017CCPC-哈尔滨站 A.Palindrome Manacher 主席树


    题面

    题意:给你一个字符串,问你满足s[i]=s[2n-i]=s[2n+i-2]的子串(这子串长度为3n-2)有多少个,原字符串长度<=5e5

    题解:对于这种子串,其实要满足2个回文,跑过一次Manacher后,len[i]表示以i向两边扩展最远的回文串长度,

            那么对于答案,实际就是统计满足下列条件(i,j)的对数

            i  <= j

           j - i <= len[i]

           j - i <= len[j]

           移项就是

           i >= j -  len[j]

           j <= i + len[i]

           那么相当于,枚举i,询问(i,i+len[i])区间内,有多少个数(这里指权值 j - len[j])小于等于i

           就是问区间内小于某个数的个数,那就是主席树裸题(好像其他人都写的树状树状ORZ)

           

     1 #include<bits/stdc++.h>
     2 #define N 500505
     3 using namespace std;
     4 int sum[N*25],rt[N*25],lc[N*25],rc[N*25];
     5 int a[N],b[N],len[N],p,node_cnt,cnt,value[N];
     6 char s[N];
     7 void build(int &t,int l, int r)
     8 {
     9     t=++node_cnt;
    10     sum[t]=0;
    11     if (l==r) return;
    12     int mid=(l+r)>>1;
    13     build(lc[t],l,mid);
    14     build(rc[t],mid+1,r);
    15 }
    16 int modify(int o,int l,int r)
    17 {
    18     int oo = ++node_cnt;
    19     lc[oo]=lc[o]; rc[oo]=rc[o]; sum[oo]=sum[o]+1;
    20     if (l==r) return oo;
    21     int mid=(l+r)>>1;
    22     if (p<=mid) lc[oo]=modify(lc[oo],l,mid);
    23     else rc[oo]=modify(rc[oo],mid+1,r);
    24     return oo;
    25 }
    26 int query(int u,int v,int l,int r,int k)
    27 {
    28     int ans,mid=((l+r)>>1);
    29     if (r<=k) return sum[v]-sum[u];
    30     if (l>k) return 0;
    31     ans=query(lc[u],lc[v],l,mid,k);
    32     if (mid<k) ans=ans+query(rc[u],rc[v],mid+1,r,k);
    33     return ans;
    34 }
    35 void manacher()
    36 {
    37     int pos=0,R=0;
    38     for (int i=1;i<=cnt;i++)
    39     {
    40         if (i<R) len[i]=min(len[2*pos-i],R-i); else len[i]=1;
    41         while (1<=i-len[i]&&i+len[i]<=cnt&&s[i-len[i]]==s[i+len[i]]) len[i]++;
    42         if (i+len[i]>R) {pos=i;R=i+len[i];}
    43     }
    44     for(int i=1;i<=cnt;i++)
    45     {
    46         a[i]=i-len[i]+1;
    47         b[i]=a[i];
    48     }
    49 }
    50 int main() 
    51 {
    52     int k, n, q, nn, v, l, r, x,T;
    53     scanf("%d
    ",&T);
    54     while (T--)
    55     {
    56         scanf("%s",s+1);
    57         cnt=strlen(s+1);
    58         manacher();
    59         sort(b+1,b+1+cnt);
    60         nn=unique(b+1,b+cnt+1)-b-1;
    61         node_cnt=0;
    62         build(rt[0],1,nn);
    63         for (int i=1;i<=cnt;i++)
    64         {
    65             p=lower_bound(b+1,b+nn+1,a[i])-b;
    66             rt[i]=modify(rt[i-1],1,nn);
    67         }
    68         long long ans=0;
    69         for (int i=1;i<=cnt;i++)
    70         {
    71             x=lower_bound(b+1,b+nn+1,i)-b;
    72             if (x==nn+1) x--;
    73             if (b[x]>i) x--;
    74             if(x==0) continue;
    75             if(min(len[i]+i-1,cnt)<i+1) continue;
    76             ans=ans+query(rt[i],rt[min(len[i]+i-1,cnt)],1,nn,x);
    77         }
    78         printf("%lld
    ",ans);
    79     }
    80 }
  • 相关阅读:
    (转载)C#如何在任务管理器中不显示指定的窗体
    Windows上配置Mask R-CNN及运行示例demo.ipynb
    如何选择普通索引和唯一索引?
    relay(跳板机)搭建
    javascript 9x9乘法口诀表
    canvas画布爆炸
    Chrome Network Timing 解释
    JavaScript中对数组的定义
    jquery each 和 map 区别
    css 兼容性转换网站
  • 原文地址:https://www.cnblogs.com/qywhy/p/9749063.html
Copyright © 2020-2023  润新知