题意:给你一个长度为n的字符串,然后进行m次删除操作,每次删除区间[l,r]内的某个字符,删除后并且将字符串往前补位,求删除完之后的字符串。
题解:
1 #include<set> 2 #include<iostream> 3 #include<string> 4 using namespace std; 5 #define lson l,m,rt<<1 6 #define rson m+1,r,rt<<1|1 7 const int N = 2e5+10; 8 int n, m; 9 int tree[N<<2]; 10 string str, tmp; 11 set<int> G[80]; 12 void PushUp(int rt) 13 { 14 tree[rt] = tree[rt<<1|1] + tree[rt<<1]; 15 } 16 void Revise(int L, int l, int r, int rt) 17 { 18 if(l == r) 19 { 20 tree[rt]++; 21 return ; 22 } 23 int m = l+r >> 1; 24 if(L <= m) Revise(L,lson); 25 else Revise(L,rson); 26 PushUp(rt); 27 } 28 int Query(int L, int R, int l, int r, int rt) 29 { 30 if(L <= l && r <= R) 31 return tree[rt]; 32 int m = l+r >> 1; 33 int ret = 0; 34 if(L <=m) ret += Query(L,R,lson); 35 if(m < R) ret+= Query(L,R,rson); 36 return ret; 37 } 38 int mian() 39 { 40 ios::sync_with_stdio(false); 41 cin.tie(0); 42 cout.tie(0); 43 cin >> n >> m; 44 cin >> str; 45 set<int>::iterator it; 46 str = "#"+str;//将字符串往右整体移动一位 47 for(int i = 1; i <= n; i++) 48 G[str[i]-‘0‘].insert(i);//将对应的位置分别存到对应的set 49 int l, r; 50 while(m--) 51 { 52 cin >> l >> r >> tmp; 53 bool flag = (l==r);//判断 l == r是否成立 如果成立可以少一次二分 54 if(l + tree[1] > n) l = n+1;//如果区间左端点大于有效长度 55 else //那么就表示不用进行删除操作了 56 { 57 int ll = l, rr = n; 58 while(ll <= rr) 59 { 60 int mm = ll + rr >> 1; 61 int num = Query(1,mm,1,n,1); 62 if(mm == num + l && str[mm] != ‘.‘) 63 { 64 l = mm; 65 break; 66 } 67 else if(mm < num+l) ll = mm+1; 68 else rr = mm-1 ; 69 } 70 } 71 if(flag) r = l; 72 else 73 { 74 if(r + tree[1] > n) r = n; 75 else 76 { 77 int ll = r, rr = n; 78 while(ll <= rr) 79 { 80 int mm = ll + rr >> 1; 81 int num = Query(1,mm,1,n,1); 82 if(mm == num + r && str[mm] != ‘.‘) 83 { 84 r = mm; 85 break; 86 } 87 else if(mm < num+r) ll = mm+1; 88 else rr = mm-1 ; 89 } 90 } 91 92 } 93 if(l == n+1) continue; 94 else 95 { 96 int pos =(int)tmp[0] - ‘0‘; 97 it = G[pos].begin(); 98 while(it != G[pos].end()) 99 { 100 int index = *it; 101 if(index >= l && index <= r && str[index] != ‘.‘) 102 { 103 Revise(index,1,n,1); 104 str[index] = ‘.‘; 105 } 106 if(index > r) break; 107 it++; 108 } 109 } 110 } 111 for(int i = 1; i <= n; i++) 112 { 113 if(str[i] != ‘.‘) 114 cout << str[i]; 115 } 116 cout << endl; 117 return 0; 118 }