codeforces 899 F - Letters Removing (线段树)
2017-12-25 21:32
393 查看
题意:给你一个长度为n的字符串,只包括大小写字母与数字,还有q个操作,对于每个操作 将[l,r]区间内删除字符ch
题解:对于这个操作l,r,是之间操作完的串的l,r,也就是你还需要找到原始串中的l,r
方法是开62个线段树,每一个维护区间和,那么对于如何寻找原来的l,r,进行前缀和的二分查找,前缀和等于l的地方就是原始串中l的地方
这题把我折磨死了= =。 62个线段树刚好卡在内存附近,打的lazy标记需要改成flag,反正是区间修改1和0
题解:对于这个操作l,r,是之间操作完的串的l,r,也就是你还需要找到原始串中的l,r
方法是开62个线段树,每一个维护区间和,那么对于如何寻找原来的l,r,进行前缀和的二分查找,前缀和等于l的地方就是原始串中l的地方
这题把我折磨死了= =。 62个线段树刚好卡在内存附近,打的lazy标记需要改成flag,反正是区间修改1和0
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> #include <queue> #include <set> #define INF 0x3f3f3f3f using namespace std; const int maxn = 2e5 + 5; typedef long long LL; char s[maxn]; int sum[maxn * 4][65]; bool lazy[maxn * 4][65]; int getid(char x){ if('a' <= x && x <= 'z') return (int)(x - 'a'); else if('A' <= x && x <= 'Z') return (int)(x - 'A' + 26); return (int)(x - '0' + 52); } void bulid(int l, int r, int o){ if(l == r){ sum[o][getid(s[l])] = 1; return; } int m = (l + r) / 2; bulid(l, m, o*2); bulid(m+1, r, o*2+1); for(int i=0; i<62; i++){ sum[o][i] = sum[o*2][i] + sum[o*2+1][i]; } } void pushdown(int o, int pos){ if(lazy[o][pos]){ sum[o*2][pos] = 0; sum[o*2+1][pos] = 0; lazy[o*2][pos] = lazy[o*2+1][pos] = lazy[o][pos]; lazy[o][pos] = false; } } void update(int l, int r, int ql, int qr, int o, int k){ if(ql <= l && qr >= r){ sum[o][k] = 0; lazy[o][k] = true; return; } int m = (l + r) / 2; for(int i=0; i<62; i++) pushdown(o,i); if(m >= ql) update(l,m,ql,qr,o*2,k); if(m < qr) update(m+1,r,ql,qr,o*2+1,k); for(int i=0; i<62; i++) sum[o][i] = sum[o*2][i] + sum[o*2+1][i]; } void print(int l, int r, int o){ if(l == r){ for(int i=0; i<62; i++) if(sum[o][i] > 0){ printf("%c",s[l]); break; } return; } int m = (l + r) / 2; for(int i=0; i<62; i++) pushdown(o,i); print(l,m,o*2); print(m+1,r,o*2+1); } int FIND(int l, int r, int o, int k){ if(l == r){ return l; } for(int i=0; i<62; i++) pushdown(o, i); int m = (l + r) / 2; int ans = 0; for(i 4000 nt i=0; i<62; i++){ ans += sum[o*2][i]; } if(ans >= k) return FIND(l,m,o*2,k); else return FIND(m+1,r,o*2+1,k - ans); } int main(){ int n,q; scanf("%d%d",&n,&q); scanf("%s",s+1); bulid(1,n,1); while(q--){ int l, r; char ch; scanf("%d%d %c",&l,&r,&ch); l = FIND(1,n,1,l); r = FIND(1,n,1,r); update(1,n,l,r,1,getid(ch)); } print(1,n,1); printf("\n"); return 0; }
相关文章推荐
- 【CodeForces】383C Propagating tree 线段树
- codeforces 739C 线段树的高级应用
- Codeforces 272C Dima and Staircase【线段树】
- codeforces 256ELucky Arrays(线段树)
- 【线段树+字符串hash】 codeforces 213E Two Permutations
- codeforces 675D D. Tree Construction(线段树+BTS)
- codeforces 266E More Queries to Array 线段树
- CodeForces 52C Circular RMQ (区间更新线段树)
- Codeforces 444C DZY Loves Colors 水线段树
- Codeforces 46 D Parking Lot(线段树区间更新模板题)
- codeforces 444 C. DZY Loves Colors(线段树)
- 【codeforces】484E. Sign on Fence 可持久化线段树
- CodeForces 570C Replacement 线段树
- Codeforces edu 6. E New Year Tree 图论 线段树
- Codeforces 487B. Strip(求区间最值+线段树上的dp)
- CodeForces 339D Xenia and Bit Operations(线段树)
- Codeforces 622C Not Equal on a Segment 【线段树 or dp】
- CodeForces 620 E.New Year Tree(线段树)
- Codeforces 629D Babaei and Birthday Cake(线段树优化dp)
- codeforces 339D 简单的线段树操作