差点把自己给做吐了
区间合并的题目,虽然自己做着很难受,做了两天,不过又加深了对区间和并以及懒标记以及相关操作的认识。
有一说一,线段树的代码真是又臭又长
- 设置了两个懒标记,一个是小明的,一个是女神的
- 女神的优先级要高于小明
- 当只对小明进行操作时,与女神没有关系。而当对女神进行操作时,小明维护的各种信息也要进行相应的操作,说白了也就是时间被占用。
当初设置的两个懒标记的姿势不太正确,冲突了
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Node{
int l, r, dlmax, drmax, dsmax, nlmax, nrmax, nsmax;
int dtag, ntag;
}node[N << 2];
void pushup(int root, int id){
if(id == 0){
if(node[root << 1].dsmax == node[root << 1].r - node[root << 1].l + 1)
node[root].dlmax = node[root << 1].dsmax + node[root << 1 | 1].dlmax;
else
node[root].dlmax = node[root << 1].dlmax;
if(node[root << 1 | 1].dsmax == node[root << 1 | 1].r - node[root << 1].r)
node[root].drmax = node[root << 1 | 1].dsmax + node[root << 1].drmax;
else
node[root].drmax = node[root << 1 | 1].drmax;
node[root].dsmax = max(max(node[root << 1].dsmax, node[root << 1 | 1].dsmax), node[root << 1].drmax + node[root << 1 | 1].dlmax);
}else{
if(node[root << 1].dsmax == node[root << 1].r - node[root << 1].l + 1)
node[root].dlmax = node[root << 1].dsmax + node[root << 1 | 1].dlmax;
else
node[root].dlmax = node[root << 1].dlmax;
if(node[root << 1 | 1].dsmax == node[root << 1 | 1].r - node[root << 1].r)
node[root].drmax = node[root << 1 | 1].dsmax + node[root << 1].drmax;
else
node[root].drmax = node[root << 1 | 1].drmax;
node[root].dsmax = max(max(node[root << 1].dsmax, node[root << 1 | 1].dsmax), node[root << 1].drmax + node[root << 1 | 1].dlmax);
if(node[root << 1].nsmax == node[root << 1].r - node[root << 1].l + 1)
node[root].nlmax = node[root << 1].nsmax + node[root << 1 | 1].nlmax;
else
node[root].nlmax = node[root << 1].nlmax;
if(node[root << 1 | 1].nsmax == node[root << 1 | 1].r - node[root << 1].r)
node[root].nrmax = node[root << 1 | 1].nsmax + node[root << 1].nrmax;
else
node[root].nrmax = node[root << 1 | 1].nrmax;
node[root].nsmax = max(max(node[root << 1].nsmax, node[root << 1 | 1].nsmax), node[root << 1].nrmax + node[root << 1 | 1].nlmax);
}
}
void build(int root, int l, int r){
node[root].l = l;
node[root].r = r;
node[root].dtag = -1;
node[root].ntag = -1;
node[root].dlmax = node[root].drmax = node[root].dsmax = node[root].nlmax = node[root].nrmax = node[root].nsmax = r - l + 1;
if(l == r){
return;
}
int mid = l + r >> 1;
build(root << 1, l, mid);
build(root << 1 | 1, mid + 1, r);
//pushup)
}
void pushdown(int root){
if(node[root].dtag != -1){
node[root << 1].dtag = node[root].dtag;
node[root << 1 | 1].dtag = node[root].dtag;
node[root << 1].dlmax = node[root << 1].drmax = node[root << 1].dsmax = node[root].dtag? 0 : node[root << 1].r - node[root << 1].l + 1;
node[root << 1 | 1].dlmax = node[root << 1 | 1].drmax = node[root << 1 | 1].dsmax = node[root].dtag? 0 : node[root << 1 | 1].r - node[root << 1].r;
node[root].dtag = -1;
}
if(node[root].ntag != -1){
node[root << 1].ntag = node[root].ntag;
node[root << 1 | 1].ntag = node[root].ntag;
node[root << 1].nlmax = node[root << 1].nrmax = node[root << 1].nsmax = node[root].ntag ? 0 : node[root << 1].r - node[root << 1].l + 1;
node[root << 1 | 1].nlmax = node[root << 1 | 1].nrmax = node[root << 1 | 1].nsmax = node[root].ntag ? 0 : node[root << 1 | 1].r - node[root << 1].r;
node[root].ntag = -1;
}
}
void change(int root, int l, int r, int id, int value){
if(node[root].l >= l && node[root].r <= r){
if(id == 0){
node[root].dlmax = node[root].drmax = node[root].dsmax = value? 0:node[root].r - node[root].l + 1;
node[root].dtag = value;
}
else{
node[root].nlmax = node[root].nrmax = node[root].nsmax = value? 0:node[root].r - node[root].l + 1;
node[root].ntag = value;
}
return;
}
pushdown(root);
int mid = node[root].l + node[root].r >> 1;
if(l <= mid)
change(root << 1, l, r, id, value);
if(r > mid)
change(root << 1 | 1, l, r, id, value);
pushup(root, id);
}
int query(int root, int len, int id){
if(node[root].l == node[root].r)
return node[root].l;
pushdown(root);
if(id == 0){
if(node[root << 1].dsmax >= len)
return query(root << 1, len, id);
else if(node[root << 1].drmax + node[root << 1 | 1].dlmax >= len)
return node[root << 1].r - node[root << 1].drmax + 1;
else
return query(root << 1 | 1, len, id);
}else{
if(node[root << 1].nsmax >= len)
return query(root << 1, len, id);
else if(node[root << 1].nrmax + node[root << 1 | 1].nlmax >= len)
return node[root << 1].r - node[root << 1].nrmax + 1;
else
return query(root << 1 | 1, len, id);
}
}
int main(){
int t, kase = 0;
cin >> t;
while(t --){
int time, n;
scanf("%d%d", &time, &n);
build(1, 1, time);
printf("Case %d:\n", ++ kase);
while(n --){
char name[10];
scanf("%s", name);
if(name[0] == 'D'){
int len;
scanf("%d", &len);
if(node[1].dsmax >= len){
int t = query(1, len, 0);
printf("%d,let's fly\n", t);
change(1, t, t + len - 1, 0, 1);
}else{
printf("fly with yourself\n");
}
}else if(name[0] == 'N'){
int len;
scanf("%d", &len);
if(node[1].dsmax >= len){
int t = query(1, len, 0);
printf("%d,don't put my gezi\n", t);
change(1, t, t + len - 1, 0, 1);
change(1, t, t + len - 1, 1, 1);
}else if(node[1].nsmax >= len){
int t = query(1, len, 1);
printf("%d,don't put my gezi\n", t);
change(1, t, t + len - 1, 0, 1);
change(1, t, t + len - 1, 1, 1);
}else{
printf("wait for me\n");
}
}else{
int x, y;
scanf("%d%d", &x, &y);
change(1, x, y, 0, 0);
change(1, x, y, 1, 0);
printf("I am the hope of chinese chengxuyuan!!\n");
}
}
}
return 0;
}
这篇博客讲述了作者在解决区间合并问题时遇到的挑战,通过两天的努力深化了对线段树、懒标记操作的理解。文章指出,线段树的代码通常复杂冗长,并且在处理小明和女神两个不同操作时,需要确保女神的优先级高于小明,同时正确处理两者间的时间占用问题。
149

被折叠的 条评论
为什么被折叠?



