• hdu6230(求限制条件的回文个数,利用manacher+BIT求解)


    题:http://acm.hdu.edu.cn/showproblem.php?pid=6230

    题意:求一个字符串中(长度<=5e5)中指定字符串个数;

       指定字符串约束为:类似俩个回文串“镶嵌”,设有俩个回文串的回文中心位置分别为x和y(x<y),前者的回文半径涵盖的范围必须包含y ,同时后者的回文半径要包含x;

    分析:

       问题可以转化为这样的(x,y)的对数;

       也就是在x回文半径范围( x,x+rl[x] ]内有多少个位置y满足y-rl[y]<=x;

       在处理时,维护以x的约束条件“y-rl[y]>x”的单调队列,单调队列过程中持续加上(x,x+rl[x] ]间的贡献 

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define lson root<<1,l,midd
    #define rson root<<1|1,midd+1,r
    #define pb push_back
    const int inf=0x3f3f3f3f;
    const ll INF=(1ll<<40);
    const int M=1e6+6;
    char s[M];
    int rl[M],p[M];
    struct BIT{
        ll tr[M];
        void init(){ memset(tr,0,sizeof(tr)); }
        void add(int x,ll c){
            for(int i=x;i<M;i+=i&-i) tr[i]+=c;
        }
        ll sum(int x){
            ll res=0;
            for(int i=x;i;i-=i&-i) res+=tr[i];
            return res;
        }
    }bit;
    ///int evenrl[M];
    void manacher(){
        int len=strlen(s);
        for(int i=len;i>=0;i--)
            s[i*2+1]=s[i],s[i*2]='#';
        int id,mx=0;
        int m=2*len+1;
        for(int i=1;i<m;i++){
            if(mx>i) p[i]=min(p[2*id-i],mx-i); else p[i]=1;
            while(s[i-p[i]]==s[i+p[i]]&&i-p[i]>=0&&i+p[i]<m)++p[i];
            if(i+p[i]>mx) id=i,mx=p[i]+i;
            if(s[i]!='#') rl[(i+1)/2]=(p[i]-1)/2;///奇数长的回文,长度不含回文中心
            ///else evenrl[(i+1)/2]=(p[i]-1)/2;///偶数长的回文,位置为左半部分末尾,长度为回文串的一半
        }
    }
    struct node{
        int val,id;
    }a[M];
    
    int main(){
        int T;
        scanf("%d",&T);
        while(T--){
            scanf("%s",s);
            int n=strlen(s);
            bit.init();
            manacher();
            for(int i=1;i<=n;i++){
                a[i].id=i;
                a[i].val=i-rl[i];
            }
            sort(a+1,a+1+n,[&](node A,node B){
                return A.val<B.val;
            });
            int x=1;
            ll ans=0;
            for(int i=1;i<=n;i++){
                while(x<=n&&a[i].val>x){
                    ans+=bit.sum(x+rl[x])-bit.sum(x);
                    x++;
                }
                bit.add(a[i].id,1);
            }
            while(x<=n){
                ans+=bit.sum(x+rl[x])-bit.sum(x);
                x++;
            }
            printf("%lld
    ",ans);
    
        }
        return 0;
    }
    View Code
  • 相关阅读:
    docker 数据卷 ---- 进阶篇
    docker 数据卷 ---- 基础篇
    python做基本的图像处理
    conv1d UpSampling1D aotoencoder 自编码代码摘录
    python daal test
    python dict 构造函数性能比较
    CNN autoencoder 进行异常检测——TODO,使用keras进行测试
    利用CNN进行流量识别 本质上就是将流量视作一个图像
    Deep Belief Network简介——本质上是在做逐层无监督学习,每次学习一层网络结构再逐步加深网络
    python pipe stdout 实现cat|grep 功能
  • 原文地址:https://www.cnblogs.com/starve/p/13849488.html
Copyright © 2020-2023  润新知