关闭

UVALive 6933 Virus synthesis(回文树)

标签: 回文树
377人阅读 评论(0) 收藏 举报
分类:
Viruses are usually bad for your health. How about ghting them with... other viruses? In this problem,
you need to nd out how to synthesize such good viruses.
We have prepared for you a set of strings of the letters A, G, T and C. They correspond to the
DNA nucleotide sequences of viruses that we want to synthesize, using the following operations:
• Adding a nucleotide either to the beginning or the end of the existing sequence.
• Replicating the sequence, reversing the copied piece, and gluing it either to the beginning or to
the end of the original (so that e.g., AGTC can become AGTCCTGA or CTGAAGTC).
We're concerned about efficiency, since we have very many such sequences, some of them very long.
Find a way to synthesize them in a minimum number of operations.
Input
The rst line of input contains the number of test cases T. The descriptions of the test cases follow:
Each test case consists of a single line containing a non-empty string. The string uses only the
capital letters `A', `C', `G' and `T' and is not longer than 100 000 characters.
Output
For each test case, output a single line containing the minimum total number of operations necessary
to construct the given sequence.
Sample Input
4
AAAA
AGCTTGCA
AAGGGGAAGGGGAA
AAACAGTCCTGACAAAAAAAAAAAAC
Sample Output
3
8
6

18

参考大牛的博客
http://www.cnblogs.com/clrs97/p/4700658.html

#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>


using namespace std;
typedef long long int LL;
const int maxn=1e5+5;
map<char,int> m;
int n;
char str[maxn];
int f[maxn];
struct Tree
{
    int next[maxn][4];
    int fail[maxn];
    int train[maxn];
    int len[maxn];
    int num[maxn];
    int cnt[maxn];
    int s[maxn];
    int last;
    int p;
    int n;
    int new_node(int x)
    {
        memset(next[p],0,sizeof(next[p]));
        len[p]=x;
        return p++;
    }
    void init()
    {
        p=0;
        new_node(0);
        new_node(-1);
        last=0;n=0;
        s[0]=-1;
        fail[0]=1;
    }
    int get_fail(int x)
    {
        while(s[n-len[x]-1]!=s[n])
            x=fail[x];
        return x;
    }
    int get_fail2(int x,int pos)
    {
        while(s[n-len[x]-1]!=s[n]||(len[x]+2)*2>len[pos])
            x=fail[x];
        return x;
    }
    void add(char xx)
    {
        int x=m[xx];
        s[++n]=x;
        int cur=get_fail(last);
        if(!(last=next[cur][x]))
        {
            int now=new_node(len[cur]+2);
			fail[now]=next[get_fail(fail[cur])][x];
			if(len[now]<=2)
				train[now]=fail[now];
			else
                train[now]=next[get_fail2(train[cur],now)][x];
            
            next[cur][x]=now;
            last=now;
        }
    }
}tree;
int ans;
int q[maxn];
int rear,head;
int main()
{
    int t;
    scanf("%d",&t);
    m['A']=0;m['C']=1;m['G']=2;m['T']=3;
    while(t--)
    {
        scanf("%s",str);
        int len=strlen(str);
        tree.init();
        ans=len;
        for(int i=0;i<len;i++)
        {
            tree.add(str[i]);
        }
        memset(f,0,sizeof(f));
        for(int i=2;i<tree.p;i++)
        {
            if(tree.len[i]&1)
                f[i]=tree.len[i];
        }
        f[0]=1;
        q[0]=0;
        head=0;rear=1;
        int x,y;
        while(head<rear)
        {
            x=q[head++];
            for(int i=0;i<4;i++)
            {
                if(tree.next[x][i])
                {
                     y=tree.next[x][i];
                    f[y]=f[x]+1;
                    f[y]=min(f[y],tree.len[y]/2-tree.len[tree.train[y]]+f[tree.train[y]]+1);
                    ans=min(ans,len-tree.len[y]+f[y]);
					q[rear++]=y;
                }
                
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}



0
0
查看评论

uvalive 7502 Suffixes and Palindromes 2015 ec (sa manacher构造 恶心

题意: 给你sa数组和manacher数组,构造字典序最小原串 由sa数组可以得到S[sa[i]] rank[sa[i+1]+1] 时, S[sa[i]] 由最长回文串可知S[L] == S[R], S[L-1] != S[R+1], 相等关系通过并查集合并,不相等关系决定了rank...
  • u013781361
  • u013781361
  • 2016-11-20 19:44
  • 317

UVALive - 6933 C - Virus synthesis

题意: 两个操作:在一个串前面或后面添加一个字母。把当前这个串double一下变成回文。 询问一个串的最小操作步数,开始为空。 题解: 答案肯定是一个回文子串的最小步数加上剩下的一个个添。 一个回文串s可以从两边加同一个字母一步花费转移过来,或者从长度小于|s|/2的回文后缀转移过来。 ...
  • u013781361
  • u013781361
  • 2017-03-21 16:03
  • 100

BZOJ4044: [Cerc2014] Virus synthesis 回文自动机

你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符放在已有串开头或者结尾 2.将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空。求最少操作次数。 len<=100000 考虑最后一次2操作,那之后的字符都是暴力拼上去的。那么可以...
  • Mima_Reincarnation
  • Mima_Reincarnation
  • 2017-05-02 21:54
  • 349

[BZOJ 4044][Cerc2014]Virus synthesis

回文自动机学习
  • Horizon_SMZ
  • Horizon_SMZ
  • 2016-03-27 10:39
  • 507

Bzoj4044:[Cerc2014] Virus synthesis:回文自动机+DP

一道回文自动机好题
  • qq_34025203
  • qq_34025203
  • 2016-03-27 16:12
  • 745

bzoj 4044: [Cerc2014] Virus synthesis 回文树

题意 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符放在已有串开头或者结尾 2.将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空。求最少操作次数。 len 分析 首先有一个结论,就是组成一个偶回文串的最后一步一定是操作二。 这...
  • qq_33229466
  • qq_33229466
  • 2018-01-18 21:39
  • 59

【bzoj4044】[Cerc2014] Virus synthesis

[Cerc2014] Virus synthesis Description 你要用ATGC四个字母用两种操作拼出给定的串: 1.将其中一个字符放在已有串开头或者结尾 2.将已有串复制,然后reverse,再接在已有串的头部或者尾部 一开始已有串为空。求最少操作次数。 len...
  • ez_2016gdgzoi471
  • ez_2016gdgzoi471
  • 2018-01-31 20:13
  • 29

【CERC2014】bzoj4044 Virus synthesis

回文自动机
  • sdfzyhx
  • sdfzyhx
  • 2017-05-18 15:23
  • 278

Codeforces Gym 100543G Virus synthesis

从这里get的思路,膜拜一下 #pragma comment(linker, "/STACK:102400000,102400000") #include #include #include #include #include #include #include #includ...
  • jtjy568805874
  • jtjy568805874
  • 2016-04-16 17:45
  • 280

【BZOJ4044】[Cerc2014] Virus synthesis【回文自动机】

【题目链接】 题解待补 /* Telekinetic Forest Guard */ #include #include #include using namespace std; const int maxn = 100005, maxq = maxn; int n, q[...
  • BraketBN
  • BraketBN
  • 2016-05-24 17:18
  • 439
    个人资料
    • 访问:131092次
    • 积分:4658
    • 等级:
    • 排名:第7453名
    • 原创:349篇
    • 转载:0篇
    • 译文:0篇
    • 评论:7条
    最新评论