CF Round 423 Div2 PC(思维题)

编程入门 行业动态 更新时间:2024-10-08 10:58:54

CF Round 423 Div2 PC(<a href=https://www.elefans.com/category/jswz/34/1770010.html style=思维题)"/>

CF Round 423 Div2 PC(思维题)

题意就是给你n个串,和这些串出现的位置,要你求满足这些条件的字典序最小的串,串的长度不超过1e6

开始想着暴力+线段树优化结果给t了,问题就在于,我优化的时候,如果这个区间就算有一个值没被优化掉那么就整个串都要被赋值一遍,并没有优化的特别好

然后看到一种让人吐血的优化方法,就是对于每个串,因为位置是严格递增的,那么我就记录上一个串的结束位置,然后从这里开始再进行赋值,(其实并没有优化多少但是过了0.0)

代码如下

 #include <iostream>  #include <cstdio>  #include <cstring>  #include <string>  #include <algorithm>  #include <cmath>  #include <map>  #include <set>  #include <stack>  #include <queue>  #include <vector>  #include <bitset>  using namespace std;  #define LL long long  const int INF = 0x3f3f3f3f;  #define MAXN 500  char s[2000006];  char ch[2000005];  int main()  {  int n,m,x;  int tot=0;  scanf("%d",&n);  for(int i=0; i<n; i++)  {  scanf("%s%d",&ch,&m);  int k=strlen(ch);  int t=-INF;  for(int j=0; j<m; j++)  {  scanf("%d",&x);  x--;  tot=max(x+k,tot);  for(int l=max(x,t); l<x+k; l++)  s[l]=ch[l-x];  t=x+k;  }  }  for(int i=0; i<tot; i++)  if(s[i]=='\0')  printf("a");  else  printf("%c",s[i]);  printf("\n");  return 0;  }  
然后看到了另外一种优化

就是我先把所有的输入数据读进来

这里就必须要用String,因为string是动态内存嘛,可以节省空间复杂度的

然后我们记录每个串的长度和起始位置


之后我们按照起始位置从小到大排序

然后也是向前面一个一样,从上一个的末尾开始进行赋值,这样时间复杂度就要小很多了,但是有点虚的,毕竟空间复杂度爆表了都

要是数据厉害点也过不了

    #include <cstdio>  #include <string>  #include <iostream>  #include <queue>  #include <cstring>  #include <algorithm>  using namespace std;  #define mst(a,b) memset((a),(b),sizeof(a))  #define rush() int T;scanf("%d",&T);while(T--)  typedef long long ll;  const int maxn= 1000005;  const int mod = 1e9+7;  const int INF = 0x3f3f3f3f;  const double eps = 1e-6;  struct node  {  int pos,id;  }a[maxn];  bool cmp(const node &a,const node &b)  {  return a.pos<b.pos;  }  string  s[maxn];  int main()  {  int n,k,x;  int cnt=0;  scanf("%d",&n);  for(int i=0;i<n;i++)  {  cin>>s[i];  scanf("%d",&k);  for(int j=0;j<k;j++)  {  scanf("%d",&x);  a[cnt].pos=x;  a[cnt++].id=i;  }  }  sort(a,a+cnt,cmp);  string ans;  int now=1;  for(int i=0;i<cnt;i++)  {  while(now<a[i].pos)  {  ans+='a';  now++;  }  for(int j=now-a[i].pos;j<s[a[i].id].length();j++)  //这里的起点是优化之处  {  ans+=s[a[i].id][j];  now++;  }  }  cout<<ans<<endl;  }  

还有一种方法就是运用并查集

开始想的是对每个连续的序列做一个集合,并记录他的l和r

这个思路应该是对的但是还是莫名其妙给wa了

然后看到另一种思路是,用并查集find_r(x)找到的是x之后最近的没有赋值的位置,这样就好些多了

还是不够有灵性啊


更多推荐

CF Round 423 Div2 PC(思维题)

本文发布于:2024-02-14 01:38:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761269.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:思维   CF   PC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!