Codeforces Round #423 Div. 2 C. String Reconstruction(瞎搞)

题目链接:Codeforces Round #423 Div. 2 C. String Reconstruction

题意:

给你n个子串和出现的位置,让你还原出字典序最小的原串。

数据保证至少有一个解。

题解:

先将所有的串用标号的方式存起来。

然后用将每个子串的出现位置放进对应的桶里。

两个子串ab的位置一共有三种情况:(只考虑a的起点大于b的起点)

一:ab不重叠。

二:ab部分重叠。

三:a子串完全包含后面b子串。

然后开一个标记记录上个出现的子串。

然后扫描整个ans,对于一,二种情况需要更新一下标记。

然后如果当前位置能被上一个出现的子串覆盖,就用上个子串来覆盖。

如果不能就赋值‘a’。

时间复杂度O(maxlen+sum(k))。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=a;i<=b;++i)
 3 using namespace std;
 4 typedef pair<int,int>P;
 5 
 6 const int N=2e6+7;
 7 P a[N];
 8 char s[N],ans[N];
 9 int now=1,n,k,x,ed,mx;
10 vector<int>g[N];
11 
12 int main(){
13     scanf("%d",&n);
14     F(i,1,n)
15     {
16         scanf("%s%d",s+now,&k);
17         int len=strlen(s+now);
18         a[i]=P(now,len);
19         now+=len;
20         F(j,1,k)
21         {
22             scanf("%d",&x);
23             mx=max(mx,x+len-1);
24             g[x].push_back(i);
25         }
26     }
27     int pre=0,idx=0;
28     F(i,1,mx)
29     {
30         for(int &it:g[i])
31         {
32             if(a[it].second+i>a[pre].second+idx)
33                 pre=it,idx=i;
34         }
35         if(a[pre].second+idx-1>=i)ans[i]=s[a[pre].first+i-idx];
36         else ans[i]='a';
37     }
38     printf("%s\n",ans+1);
39     return 0;
40 }
View Code

 

转载于:https://www.cnblogs.com/bin-gege/p/7163205.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值