Codeforces Round #423 (Div. 2, rated, based on VK Cup Finals)
从给出信息片段,得出字典序最小的一个字符串,题目保证答案存在
信息给出形式:
3
a 4 1 3 5 7
ab 2 1 5
ca 1 4
第一行 3 代表信息片段个数
第二行 a 代表片段信息, 4 代表在4个地方出现 1,3,5,7 分别代表出现的位置
.
.
输出:
abacaba
题目给出片段信息和出现位置,相当于给出区间
为避免对已操作区间重复操作,用树状数组加以标记,标记方式为,访问标记为1,未访问为0,树状数组求和,若某区间的和不与区间长度相等,则该区间未标记完全.
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 2001000; 6 7 char ans[maxn]; 8 char c[maxn]; 9 int t[maxn]; 10 11 void add(int k) 12 { 13 while(k <= maxn) 14 { 15 t[k]++; 16 k += k & -k; 17 } 18 } 19 int sum(int l, int r) 20 { 21 l--; //左右都包括 22 int suml = 0; 23 while(l) 24 { 25 suml += t[l]; 26 l -= l & -l; 27 } 28 int sumr = 0; 29 while(r) 30 { 31 sumr += t[r]; 32 r -= r & -r; 33 } 34 return sumr - suml; 35 } 36 37 void updata(int l, int r, int k) 38 { 39 if(l == r) 40 { 41 if(!ans[l]) 42 { 43 add(l); 44 ans[l] = c[k]; 45 } 46 return ; 47 } 48 int mid = (l + r) >> 1; 49 if(sum(l, mid) < mid - l + 1) updata(l, mid, k); 50 if(sum(mid + 1, r) < r - mid) updata(mid + 1, r, k + mid - l + 1); 51 } 52 53 int main() 54 { 55 int n; 56 while(scanf("%d", &n) != EOF) 57 { 58 int lans = 0; 59 memset(ans,0,sizeof(ans)); 60 memset(t,0,sizeof(t)); 61 while(n--) 62 { 63 int m = 0; 64 scanf("%s%d", c, &m); 65 int len = strlen(c); 66 for(int i = 0; i < m; i++) 67 { 68 int l = 0; 69 scanf("%d", &l); 70 lans = max(lans, l + len); 71 updata(l, l + len - 1, 0); 72 } 73 } 74 for(int i = 1; i < lans; i++) 75 { 76 putchar(ans[i]? ans[i]: ‘a‘); 77 } 78 printf("\n"); 79 } 80 return 0; 81 }
用并查集标记已被访问区域,标记方式为,已被访问区域所有元素的根设为最近未被访问的元素,这样不仅标记了访问区域,访问时还提供一个到未访问区域的方向.
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 2000100; 6 7 char ans[maxn]; 8 char c[maxn]; 9 int fa[maxn]; 10 11 int f(int x) 12 { 13 return x == fa[x] ? x : fa[x] = f(fa[x]); 14 } 15 16 int main() 17 { 18 int n; 19 while(scanf("%d", &n) != EOF) 20 { 21 int lans = 0; 22 memset(ans,0,sizeof(ans)); 23 for(int i = 0; i < maxn; i++) fa[i] = i; 24 while(n--) 25 { 26 int m = 0; 27 scanf("%s%d", c, &m); 28 int len = strlen(c); 29 for(int i = 0; i < m; i++) 30 { 31 int l = 0; 32 scanf("%d", &l); 33 lans = max(lans,l+len); 34 for(int j = f(l); j < l + len; j++) 35 { 36 fa[j] = max(f(l + len),fa[j]); 37 ans[j] = c[j-l]; 38 } 39 } 40 } 41 for(int i = 1; i < lans; i++) 42 { 43 putchar(ans[i]? ans[i] : ‘a‘); 44 } 45 printf("\n"); 46 } 47 return 0; 48 }
时间: 2024-08-24 20:05:52