zoukankan      html  css  js  c++  java
  • 2017中国大学生程序设计竞赛-哈尔滨站 A

    Palindrome

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 426    Accepted Submission(s): 163


    Problem Description
    Alice like strings, especially long strings. For each string, she has a special evaluation system to judge how elegant the string is. She defines that a string S[1..3n2](n2) is one-and-half palindromic if and only if it satisfies S[i]=S[2ni]=S[2n+i2](1in).For example, abcbabc is one-and-half palindromic string, and abccbaabc is not. Now, Alice has generated some long strings. She ask for your help to find how many substrings which is one-and-half palindromic.
     
    Input
    The first line is the number of test cases. For each test case, there is only one line containing a string(the length of strings is less than or equal to 500000), this string only consists of lowercase letters.
     
    Output
    For each test case, output a integer donating the number of one-and-half palindromic substrings.
     
    Sample Input
    1 ababcbabccbaabc
     
    Sample Output
    2
    /*************************************************************************
        > File Name: A.cpp
        > Author: LyuCheng
        > Created Time: 2017-12-01 21:54
        > Description: 
            题意:给你一个字符串问你有多少个子串满足s[i]=s[2*n-i]=s[2*n+i-2]
    
            思路:满足条件的子串实际上是关于两点回文的一个子串,并且这个回文串
                   一定是奇数回文,用马拉车算法求出以每个点的回文半径,如果满足题
                目的条件,设i<j是这个子串的两个回文点,那么i-j<=pos[i]&&i-j<=pos[j]
                用树状数组记录一下,然后统计
     ************************************************************************/
    #include <bits/stdc++.h>
    
    #define MAXN 567890
    #define lowbit(x) x&(-x)
    #define LL long long
    
    using namespace std;
    
    int t;
    int n;
    char str[MAXN<<1];
    char tmp[MAXN<<1];
    int Len[MAXN<<1];
    int pos[MAXN<<1];
    int c[MAXN<<1];
    LL res;
    vector<int>v[MAXN<<1];
    
    inline void update(int x){
        while(x<MAXN){
            c[x]++;
            x+=lowbit(x);
        }
    }
    
    inline int getsum(int x){
        int s=0;
        while(x>0){
            s+=c[x];
            x-=lowbit(x);
        }
        return s;
    }
    
    int cal(char *st){
        int i,len=strlen(st);
        tmp[0]='@';//字符串开头增加一个特殊字符,防止越界
        for(i=1;i<=2*len;i+=2){
            tmp[i]='#';
            tmp[i+1]=st[i/2];
        }
        tmp[2*len+1]='#';
        tmp[2*len+2]='$';//字符串结尾加一个字符,防止越界
        tmp[2*len+3]=0;
        return 2*len+1;//返回转换字符串的长度
    }
    //Manacher算法计算过程
    int manacher(char *st,int len){
         int mx=0,ans=0,po=0;//mx即为当前计算回文串最右边字符的最大值
         for(int i=1;i<=len;i++){
             if(mx>i)
                 Len[i]=min(mx-i,Len[2*po-i]);//在Len[j]和mx-i中取个小
             else
                 Len[i]=1;//如果i>=mx,要从头开始匹配
             while(st[i-Len[i]]==st[i+Len[i]])
                 Len[i]++;
             if(Len[i]+i>mx){//若新计算的回文串右端点位置大于mx,要更新po和mx的值
                 mx=Len[i]+i;
                 po=i;
             }
             ans=max(ans,Len[i]);
         }
         return ans-1;//返回Len[i]中的最大值-1即为原串的最长回文子串额长度
    }
    inline void init(){
        memset(str,'',sizeof str);
        memset(tmp,'',sizeof tmp);
        memset(c,0,sizeof c);
        memset(pos,0,sizeof pos);
        for(int i=0;i<MAXN;i++)
            v[i].clear();
        res=0;
    }
    
    int main(){
        scanf("%d",&t);
        while(t--){
            init();
            scanf("%s",str);
            n=cal(str);
            manacher(tmp,n);
            int p=0;
            for(int i=2;i<n;i+=2){
                pos[++p]=Len[i]/2-1;
                v[p-pos[p]].push_back(p);
            }
            n=strlen(str);    
            for(int i=1;i<=n;i++){
                for(int j=0;j<(int)v[i].size();j++)
                    update(v[i][j]);
                res+=getsum(min(i+pos[i],n))-getsum(i);
            }    
            printf("%lld
    ",res);    
        }
        return 0;
    }
  • 相关阅读:
    SQL union用法转载自http://www.cnblogs.com/johngong/archive/2008/04/25/1170519.html
    jquery ajax调用后台方法返回json数据转自http://www.cnblogs.com/xiaoxi/archive/2011/03/31/2000803.html
    我所知道的CallbackContract in WCF
    我所知道的CallbackContract in WCF
    使用Web.Config Transformation配置灵活的配置文件
    InfluxDB基本概念和操作
    ContentControl 的使用
    jsp_servlet时序图
    insertAdjacentHTML和insertAdjacentText方法(转)
    在Javascript中Eval函数的使用(转)
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/7944832.html
Copyright © 2011-2022 走看看