题意:给定n个子串,和每个子串在原串中的出现位置(每个子串可能出现多次),问字典序最小的原串是什么。
思路:这题暴力3分钟就写完了,然而并不敢交,想了很长时间的优化也就想到了记录每个位置的结束点,然并卵,大数据该T还是T。
正解:利用类似并查集寻根函数的思想维护区间端点,以前做过类似的题的,昨晚不知为啥脑抽就是想不起来。。
PS:不加并查集的路径压缩,直接一个next数组也是能水过的。
代码:
#include<bits/stdc++.h>
#define ll long long
#define pi acos(-1)
#define MAXN 100010
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int>P;
char ans[MAXN*100];
char s[MAXN*10];
int f[MAXN*100];
int getf(int k)
{
return k==f[k]?k:f[k]=getf(f[k]);
}
int main()
{
int n,k,LEN=0,id;
cin>>n;
for(int i=0;i<MAXN*100;i++)
f[i]=i;
for(int i=0;i<n;i++)
{
scanf("%s %d",s,&k);
int len=strlen(s);
while(k--)
{
scanf("%d",&id);
for(int i=getf(id);i<id+len;i=f[i]=getf(i+1))
{
ans[i]=s[i-id];
}
LEN=max(LEN,id+len);
}
}
for(int i=1;i<LEN;i++)
{
if(ans[i]=='\0')
ans[i]='a';
}
puts(ans+1);
return 0;
}