首页 > 代码库 > URAL 1019. Line Painting 线段树 区间合并 离散化
URAL 1019. Line Painting 线段树 区间合并 离散化
题目来源:URAL 1019. Line Painting
题意:求最长的一段全部为白色的区间
思路:线段树成段更新 区间合并 离散化 这里对应的是一段区间 所以每次不是m+1 而是 l m 和 m r 了 另外我加上了0 和 10^9 这两个点
每一段区间(l, r)我记录的是l和r之间有多少条线段
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 50010; int sum[maxn<<2], lsum[maxn<<2], rsum[maxn<<2], co[maxn<<2]; struct node { int x, v, id; }c[maxn*2]; int num[maxn*2]; char s[maxn][5]; void pushup(int l, int r, int rt) { int k = r-l+1; int m = (l+r) >> 1; lsum[rt] = lsum[rt<<1]; rsum[rt] = rsum[rt<<1|1]; if(lsum[rt] == num[m]-num[l]) lsum[rt] += lsum[rt<<1|1]; if(rsum[rt] == num[r]-num[m]) rsum[rt] += rsum[rt<<1]; sum[rt] = max(sum[rt<<1], sum[rt<<1|1]); sum[rt] = max(sum[rt], rsum[rt<<1]+lsum[rt<<1|1]); } void build(int l, int r, int rt) { sum[rt] = lsum[rt] = rsum[rt] = num[r]-num[l]; co[rt] = -1; if(l + 1 == r) return; int m = (l+r) >> 1; build(l, m, rt<<1); build(m, r, rt<<1|1); //pushup(l, r, rt); } void pushdown(int l, int r, int rt) { if(co[rt] != -1) { int k = r-l+1; int m = (l + r) >> 1; sum[rt<<1] = co[rt]*(num[m]-num[l]); lsum[rt<<1] = co[rt]*(num[m]-num[l]); rsum[rt<<1] = co[rt]*(num[m]-num[l]); sum[rt<<1|1] = co[rt]*(num[r]-num[m]); lsum[rt<<1|1] = co[rt]*(num[r]-num[m]); rsum[rt<<1|1] = co[rt]*(num[r]-num[m]); co[rt<<1] = co[rt<<1|1] = co[rt]; co[rt] = -1; } } int query(int l, int r, int rt, int a) { if(l + 1 == r) return r; pushdown(l, r, rt); int m = (l+r) >> 1; //printf("*****%d %d %d %d %d\n", l, r, sum[rt<<1], sum[rt<<1|1], a); if(sum[rt<<1] >= a) return query(l, m, rt<<1, a); else if(rsum[rt<<1] + lsum[rt<<1|1] >= a) return query(m, r, rt<<1|1, a-rsum[rt<<1]); else return query(m, r, rt<<1|1, a); } void update(int x, int y, int l, int r, int rt, int c) { if(x == l && y == r) { sum[rt] = lsum[rt] = rsum[rt] = c ? (num[r]-num[l]) : 0; co[rt] = c; return; } pushdown(l, r, rt); int m = (l+r) >> 1; if(y <= m) update(x, y, l, m, rt<<1, c); else if(x >= m) update(x, y, m, r, rt<<1|1, c); else { update(x, m, l, m, rt<<1, c); update(m, y, m, r, rt<<1|1, c); } pushup(l, r, rt); } bool cmp1(node a, node b) { return a.x < b.x; } bool cmp2(node a, node b) { return a.id < b.id; } int main() { int q; while(scanf("%d", &q) != EOF) { for(int i = 0; i < q*2; i++) { scanf("%d", &c[i].x); c[i].id = i; if(i&1) scanf("%s", s[(i-1)/2]); } sort(c, c+2*q, cmp1); int now = c[0].x, n = 2; num[1] = 0; for(int i = 0; i < q*2; i++) { if(now != c[i].x) { n++; now = c[i].x; } c[i].v = n; num[n] = now; } num[++n] = 1000000000; //for(int i = 1; i <= n; i++) //printf("***%d\n", num[i]); //printf("%d\n", n); sort(c, c+2*q, cmp2); build(1, n, 1); for(int i = 0; i < q; i++) { int a = c[i<<1].v; int b = c[i<<1|1].v; int color = 1; if(s[i][0] == 'b') color = 0; update(a, b, 1, n, 1, color); //printf("***%d %d %d\n", a, b, sum[1]); } int ans = query(1, n, 1, sum[1]); printf("%d %d\n", num[ans]-sum[1], num[ans]); } return 0; }
URAL 1019. Line Painting 线段树 区间合并 离散化
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。