HDU-5157Harry and magic string

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

先从后往前插点,在构造回文树时,让cnt[i]+=cnt[fail[i]],然后维护一个后缀和a。

再从前往后插点,每个点对答案的贡献为cnt[i]*a[i+1]

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>
#define rep(i,l,r) for (int i=l;i<=r;i++)
#define down(i,l,r) for (int i=l;i>=r;i--)
#define clr(x,y) memset(x,y,sizeof(x))
#define ll long long
#define maxn 200500
using namespace std;
ll a[maxn],ans;
char ch[maxn];
int read(){
    int x=0,f=1; char ch=getchar();
    while (!isdigit(ch)) {if (ch==‘-‘) f=-1; ch=getchar();}
    while (isdigit(ch)) {x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
struct data{
    ll sum;
    int n,tot,fail[maxn],l[maxn],nxt[maxn][30],s[maxn],last,cnt[maxn];
    int newnode(int len){
        clr(nxt[tot],0);
        l[tot]=len; cnt[tot]=0;
        return tot++;
    }
    void init(){
        tot=0; sum=0; clr(fail,0);
        newnode(0); newnode(-1);
        fail[0]=1;
        last=1;
        s[0]=-1;
        n=0;
    }
    int getfail(int v){
        while (s[n-l[v]-1]!=s[n]) v=fail[v];
        return v;
    }
    int add(int c){
        s[++n]=c;
        int cur=getfail(last);
        if (!nxt[cur][c]){
            int now=newnode(l[cur]+2);
            fail[now]=nxt[getfail(fail[cur])][c];
            nxt[cur][c]=now;
            cnt[now]=cnt[fail[now]]+1;
        } last=nxt[cur][c];
        return cnt[last];
    }
}T;
int main(){
 //   freopen("in.txt","r",stdin);
    while (~scanf("%s",ch)){
        clr(a,0); ans=0;
        int len=strlen(ch);
        T.init();
        down(i,len-1,0){
            a[i]=a[i+1]+T.add(ch[i]-‘a‘);
        }
    //    down(i,len-1,0) printf("%lld ",a[i]);
        T.init();
        rep(i,0,len-1) {
            ans+=a[i+1]*T.add(ch[i]-‘a‘);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-11-07 09:44:56

HDU-5157Harry and magic string的相关文章

HDU 5157 Harry and magic string(回文树)

Harry and magic string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 223    Accepted Submission(s): 110 Problem Description Harry got a string T, he wanted to know the number of T's disjoint

hdu 5030 Rabbit&#39;s String(后缀数组&amp;二分)

Rabbit's String Time Limit: 40000/20000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 288    Accepted Submission(s): 108 Problem Description Long long ago, there lived a lot of rabbits in the forest. One day, the

hdu 3183 A Magic Lamp(RMQ)

A Magic Lamp                                                                               Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description Kiki likes traveling. One day she finds a magic lamp, u

HDU 4421 Bit Magic(2-sat)

HDU 4421 Bit Magic 题目链接 题意:就依据题目,给定b数组.看能不能构造出一个符合的a数组 思路:把每一个数字的每一个二进制位单独考虑.就变成一个2-sat题目了,依据题目中的式子建立2-sat的边.然后每一位跑2-sat.假设每位都符合.就是YES,假设有一位不符合就是NO 代码: #include <cstdio> #include <cstring> #include <cstdlib> #include <vector> #incl

J - Just a Magic String

J - Just a Magic String Time Limit: 1000/1000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others) Description You have such a string $S$ a, every time you can copy $S$ to $T$ ,change a in $T$ to b, b to a, then add $T$ after $S$. For exam

hdu 5030 Rabbit&#39;s String(后缀数组)

题目链接:hdu 5030 Rabbit's String 题目大意:给定k和一个字符串,要求将字符串拆分成k个子串.然后将每个子串中字典序最大的子串选出来,组成一个包含k个字符串的集合,要求这个集合中字典序最大的字符串字典序最小. 解题思路:网赛的时候试图搞了一下这道题,不过水平还是有限啊,后缀数组也是初学,只会切一些水题.赛后看了一下别人的题解,把这题补上了. 首先对整个字符串做后缀数组,除了处理出sa,rank,height数组,还要处理处f数组,f[i]表示说以0~sa[i]开头共有多少

HDU 5030 Rabbit&#39;s String

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5030 题意:给出一个长度为n的串S,将S分成最多K个子串S1,S2,……Sk(k<=K).选出每个子串Si(1<=i<=k)的最大子串SSi.最后使得k个SSi的最大值最小. 思路:首先用后缀数组求出所有子串.二分答案串,判定是否存在一种分法满足要求.对于答案串A,设A起始位置所组成的后缀排名为t,在排名为[t+1,n]的后缀中截取子串S[Li,Ri],使得Ri<n(下标1到n),且该

hdu 3336 Count the string

Count the stringTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4239    Accepted Submission(s): 1977 Problem Description It is well known that AekdyCoin is good at string problems as well as num

HDU 3973 AC&#39;s String (substr 强行匹配)

AC's String Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1127    Accepted Submission(s): 316 Problem Description You are given some words {Wi}. Then our stupid AC will give you a very long

hdu 3183 A Magic Lamp(RMQ)

题目链接:hdu 3183 A Magic Lamp 题目大意:给定一个字符串,然后最多删除K个,使得剩下的组成的数值最小. 解题思路:问题等价与取N-M个数,每次取的时候保证后面能取的个数足够,并且取的数最小,查询最小的操作用RMQ优化. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 10005; int N, M, d[m