Gym 101194F Mr. Panda and Fantastic Beasts

#include<bits/stdc++.h>
using namespace std;
#define ms(arr,a) memset(arr,a,sizeof arr)
#define debug(x) cout<<"< "#x" = "<<x<<" >"<<endl
const int maxn=4e5;
const int INF=0x3f3f3f3f;
char s[maxn];
int sa[maxn],Rank[maxn],height[maxn],a[maxn],b[maxn],rmq[maxn][50];
int x[maxn],y[maxn],c[maxn];
int len,tot;
void build()
{
    int n=strlen(s),m=128;
    //int *x=new int[n],*y=new int[n],*c=new int[n+128];
    for(int i=0;i<m;++i)c[i]=0;
    for(int i=0;i<n;++i)c[x[i]=s[i]]++;
    for(int i=1;i<m;++i)c[i]=c[i]+c[i-1];
    for(int i=n-1;i>=0;--i)sa[--c[x[i]]]=i;
    for(int k=1;k<=n;k<<=1)
    {
        int p=0;
        for(int i=n-k;i<n;++i)y[p++]=i;
        for(int i=0;i<n;++i)if(sa[i]>=k)y[p++]=sa[i]-k;
        for(int i=0;i<m;++i)c[i]=0;
        for(int i=0;i<n;++i)c[x[y[i]]]++;
        for(int i=1;i<m;++i)c[i]+=c[i-1];
        for(int i=n-1;i>=0;--i)sa[--c[x[y[i]]]]=y[i];
        swap(x,y);
        p=1;x[sa[0]]=0;
        for(int i=1;i<n;++i)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
        if(p>=n)break;
        m=p;
    }
    //delete[] x,y,c;
    for(int i=0;i<n;++i)Rank[sa[i]]=i;
    int len=0;
    for(int i=0;i<n;++i)
    {
        if(len)len--;
        if(Rank[i]==0)continue;
        int j=sa[Rank[i]-1];
        while(s[i+len]==s[j+len])len++;
        height[Rank[i]]=len;
    }
    for(int i=1;i<n;++i)rmq[i][0]=height[i];
    for(int i=1;(1<<i)<n;++i)for(int j=1;j+(1<<i)<=n;++j)rmq[j][i]=min(rmq[j][i-1],rmq[j+(1<<(i-1))][i-1]);
}
int lcp(int a,int b)
{
    if(a==b)return strlen(s+sa[a]);
    if(a>b)swap(a,b);
    int k=0;
    while((1<<(k+1))<=b-a)k++;
    return min(rmq[a+1][k],rmq[b-(1<<k)+1][k]);
}
int main()
{
    freopen("Input.txt","r",stdin);
    int T;scanf("%d",&T);
    for(int Case=1;Case<=T;++Case)
    {

        int n;
        scanf("%d%s",&n,s);
        len=strlen(s);
        for(int i=0;i<n-1;++i)
        {
            int pos=strlen(s);
            s[pos]=‘.‘;
            scanf("%s",s+pos+1);
        }
        tot=strlen(s);
        build();
        int tmp=0;
        a[0]=-1,b[tot-1]=-1;
        for(int i=1;i<tot;++i)
        {
            if(sa[i-1]<len)a[i]=a[i-1];
            else a[i]=i-1;
            if(sa[tot-i]<len)b[tot-i-1]=b[tot-i];
            else b[tot-i-1]=tot-i;
        }
        int ans=INF,ansp;
        for(int i=0;i<len;++i)
        {
            int pos=Rank[i],mLen;
            if(a[pos]==-1)mLen=lcp(pos,b[pos]);
            else if(b[pos]==-1)mLen=lcp(pos,a[pos]);
            else mLen=max(lcp(pos,b[pos]),lcp(pos,a[pos]));
            if(mLen+i>=len)break;
            mLen++;
            if(mLen<ans)ans=mLen,ansp=pos;
            if(mLen==ans&&pos<ansp)ansp=pos;
        }
        printf("Case #%d: ",Case);
        if(ans==INF)printf("Impossible\n");
        else
        {
            for(int i=0;i<ans;++i)printf("%c",s[sa[ansp]+i]);
            printf("\n");
        }
    }
}

原文地址:https://www.cnblogs.com/maoruimas/p/9800125.html

时间: 2024-10-29 02:50:13

Gym 101194F Mr. Panda and Fantastic Beasts的相关文章

[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts

地址:http://codeforces.com/gym/101194 题目:略 思路: 这题做法挺多的,可以sam也可以后缀数组,我用sam做的. 1.我自己yy的思路(瞎bb的) 把第一个串建立sam,然后让其他串在上面跑. 每走到一个位置p,当前长度为num,就代表这个endpos集合里的长度小于等于num的字符串是被包含了,同时parent树的所有祖先节点也要标记为被包含. 这一步的具体做法是:用一个mi数组表示到达该节p点时的长度大于mi[p]时,才算未被包含(到达长度指的是从root

hdu6007 Mr. Panda and Crystal 最短路+完全背包

/** 题目:hdu6007 Mr. Panda and Crystal 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6007 题意:魔法师有m能量,有n种宝石,有些宝石给定了用魔法变出它需要的能量,以及该宝石可以卖出的价钱. 有些宝石没有给出,给出k个方程,表示某些宝石可以通过另外一些宝石合成. 求魔法师最多可以卖出多少钱. 思路: 处理方程,最短路求出所有的宝石用能量变出的最小能量值. 然后完全背包. */ #include<iostream>

Gym 101194C / UVALive 7899 - Mr. Panda and Strips - [set][2016 EC-Final Problem C]

题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5921 题意: 一个长度为 $N$ 的序列,要求选出两段不重叠的区间,要求两个区间包含的元素均互不相同,求两段区间的长度和最大为多少. 题解: (主要参考https://blo

Mr. Panda and Crystal HDU - 6007 最短路+完全背包

题目:题目链接 思路:不难看出,合成每个宝石需要消耗一定的魔力值,每个宝石有一定的收益,所以只要我们知道每个宝石合成的最小花费,该题就可以转化为一个背包容量为初始魔力值的完全背包问题,每个宝石的最小花费可以用dijkstra跑一遍最短路算出,路径长度用合成花费表示. AC代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #in

【费用流】 ICPC 2016 China Final J. Mr.Panda and TubeMaster

表示“必须选”的模型 题目大意 题目分析 一个格子有四种方式看上去很难处理.将横竖两个方向分开考虑,会发现:因为收益只与相邻格子是否连通有关,所以可以将一个格子拆成表示横竖两个方向的,互相独立的点. 上图的格子里四个方向红边表示的就是一个格子的可能方向:拆点后所连蓝边的容量为1,费用即为连通两个格子的收益. 但是这样建图不能够表示某些格子必须要选. 考虑一个格子如果被选择了会发生什么:因为每个格子都处在环上,那么被选择的网格一定可以通过其他节点走到汇点.这意味着一个格子拆成的两个节点之间的边就可

2016-2017 ACM-ICPC CHINA-Final

A Gym 101194A Number Theory Problem B Gym 101194B Hemi Palindrome C Gym 101194C Mr. Panda and Strips D Gym 101194D Ice Cream Tower E Gym 101194E Bet F Gym 101194F Mr. Panda and Fantastic Beasts G Gym 101194G Pandaria H Gym 101194H Great Cells I Gym 1

2016-2017 ACM-ICPC CHINA-Final Solution

Problem A. Number Theory Problem Solved. 水. 1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1e5 + 10; 6 7 typedef long long ll; 8 9 int n; 10 ll arr[maxn], ans[maxn]; 11 12 void Init() 13 { 14 arr[0] = 1; 15 for(int i = 1; i

退役前的做题记录3

[CERC2017]Gambling Guide 设 \(f_u\) 表示 \(u\) 到 \(n\) 的期望. \(f_n=0\) \[f_u=1+\sum_{v\in suf_v}\frac{min(f_u,f_v)}{d_u}\] \[\rightarrow f_u=1+\sum_{v\in suf_u,f_v<f_u}\frac{f_v}{d_u}+\sum_{v\in suf_u,f_v\ge f_u}\frac{f_u}{d_u}\] \[\rightarrow f_u=\sum_{

Ice Cream Tower

2017-08-18 21:53:38 writer:pprp 题意如下: Problem D. Ice Cream Tower Input file: Standard Input Output file: Standard Ouptut Time limit: 6 seconds Mr. Panda likes ice cream very much especially the ice cream tower. An ice cream tower consists of K ice cr