[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出发经过某条路径到p的长度),所以其他串在sam上走到每个节点p,长度为num时,记录下mi[p]=max(mi[p],num);

    再跑完所有串后,来更新parent树上的节点。先拓扑排序,然后如果mi[p]>0,mi[fa[p]]=len[p],否则mi[p]=len[fa[p]]。(mi数组初始时为0)

    这样可以在O(n)更新parent树.

    然后再扫一遍节点,如果mi[p]<len[p],anslen=min(anslen,mi[p]+1),这样就得到了anslen。(anslen为最小串的长度)

    在扫一遍节点把所有可行答案求个字典序最小的就行了。(这一步远远没有O(anslen*|p|),p是可行答案集合的大小,时间复杂度可以看下一个做法的时间)

  2.网上看到的做法

    把其他串建立广义sam,然后让第一个串在上面跑。

    这样每当失配的时候,沿parent树走到符合条件的节点p,则此时最小可行字符串长度为len[fa[p]]+2,拿他去更新答案即可。

    这做法时间复杂度更高,因为字符串比较次数比做法一多(它可能比较了长度大于anslen的字符串),且建立sam的时间复杂度也高。

贴个做法2的代码把,一的不想写了

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 struct SAM
  6 {
  7     static const int MAXN = 1000001<<1;//大小为字符串长度两倍
  8     static const int LetterSize = 26;
  9
 10     int tot, last, ch[MAXN][LetterSize], fa[MAXN], len[MAXN];
 11     int sum[MAXN], tp[MAXN], cnt[MAXN]; //sum,tp用于拓扑排序,tp为排序后的数组
 12
 13     void init( void)
 14     {
 15         last = tot = 1;
 16         len[1] = 0;
 17         memset( ch[1], 0, sizeof ch[1]);
 18     }
 19
 20     void add( int x)
 21     {
 22         int p = last, np = last = ++tot;
 23         len[np] = len[p] + 1, cnt[last] = 1;
 24         memset( ch[np], 0, sizeof ch[np]);
 25         while( p && !ch[p][x]) ch[p][x] = np, p = fa[p];
 26         if( p == 0)
 27             fa[np] = 1;
 28         else
 29         {
 30             int q = ch[p][x];
 31             if( len[q] == len[p] + 1)
 32                 fa[np] = q;
 33             else
 34             {
 35                 int nq = ++tot;
 36                 memcpy( ch[nq], ch[q], sizeof ch[q]);
 37                 len[nq] = len[p] + 1, fa[nq] = fa[q], fa[q] = fa[np] = nq;
 38                 while( p && ch[p][x] == q)  ch[p][x] = nq, p = fa[p];
 39             }
 40         }
 41     }
 42
 43     void toposort( void)
 44     {
 45         for(int i = 1; i <= len[last]; i++)   sum[i] = 0;
 46         for(int i = 1; i <= tot; i++)   sum[len[i]]++;
 47         for(int i = 1; i <= len[last]; i++)   sum[i] += sum[i-1];
 48         for(int i = 1; i <= tot; i++)   tp[sum[len[i]]--] = i;
 49     }
 50
 51     void go(char *ss)
 52     {
 53         int mi=0x3f3f3f3f,l;
 54         for(int i=0,p=1,num=0,slen=strlen(ss);i<slen;i++)
 55         {
 56             int c=ss[i]-‘a‘;
 57             if(ch[p][c])    p=ch[p][c],num++;
 58             else
 59             {
 60                 while(p&&!ch[p][c]) p=fa[p];
 61                 if(p)
 62                     num=len[p]+1,p=ch[p][c];
 63                 else
 64                     p=1,num=0;
 65                 if(num+1<mi)    mi=num+1,l=i-num;
 66                 else if(num+1==mi)
 67                 for(int j=l,k=i-num;k<=i;k++,j++)
 68                 if(ss[j]!=ss[k])
 69                 {
 70                     if(ss[j]>ss[k]) l=i-num;
 71                     break;
 72                 }
 73             }
 74         }
 75         if(mi==0x3f3f3f3f)
 76             printf("Impossible");
 77         else
 78             for(int i=0;i<mi;i++)
 79                 printf("%c",ss[i+l]);
 80     }
 81 } sam;
 82
 83 char sa[1000000],sb[1000000];
 84 int main(void)
 85 {
 86     int t,n,cs=1;cin>>t;
 87     while(t--)
 88     {
 89         sam.init();
 90         scanf("%d%s",&n,sa);
 91         for(int i=1;i<n;i++)
 92         {
 93             scanf("%s",sb);
 94             for(char *p=sb;*p;p++)  sam.add(*p-‘a‘);
 95             sam.last=1;
 96         }
 97         printf("Case #%d: ",cs++);
 98         sam.go(sa);
 99         printf("\n");
100     }
101     return 0;
102 }
时间: 2024-10-05 10:20:12

[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts的相关文章

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

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

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

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

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

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

【费用流】 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

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

内地电影票房总排行榜

WORLDWIDE GROSSES#1-100 - #101-200 - #201-300 - #301-400 - #401-500 - #501-600 - #601-700 - #701-705 Pink highlight = official revisions of older moviesGold highlight = now playing or recent movies Rank Title Studio Worldwide Domestic / % Overseas /