比赛 |
[不是Rapiz出的]农场主钦定NOIP模拟赛1 |
评测结果 |
WWWEEEEEEE |
题目名称 |
Color the Axis |
最终得分 |
0 |
用户昵称 |
Twist Fate |
运行时间 |
0.552 s |
代码语言 |
C++ |
内存使用 |
0.90 MiB |
提交时间 |
2016-11-08 19:09:29 |
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxnode = 1<<17;
int _sum,op, qL, qR, v;
struct IntervalTree {
int sumv[maxnode], setv[maxnode];
// 维护信息
void maintain(int o, int L, int R) {
int lc = o*2, rc = o*2+1;
if(R > L) {
sumv[o] = sumv[lc] + sumv[rc];
}
if(setv[o] >= 0) { sumv[o] = setv[o] * (R-L+1); }
}
// 标记传递
void pushdown(int o) {
int lc = o*2, rc = o*2+1;
if(setv[o] >= 0) { //本结点有标记才传递。注意本题中set值非负,所以-1代表没有标记
setv[lc] = setv[rc] = setv[o];
setv[o] = -1; // 清除本结点标记
}
}
void update(int o, int L, int R) {
int lc = o*2, rc = o*2+1;
if(qL <= L && qR >= R) { // 标记修改
setv[o] = v;
} else {
pushdown(o);
int M = L + (R-L)/2;
if(qL <= M) update(lc, L, M); else maintain(lc, L, M);
if(qR > M) update(rc, M+1, R); else maintain(rc, M+1, R);
}
maintain(o, L, R);
}
void query(int o, int L, int R) {
if(setv[o] >= 0) { // 递归边界1:有set标记
_sum += setv[o] * (min(R,qR)-max(L,qL)+1);
} else if(qL <= L && qR >= R) { // 递归边界2:边界区间
_sum += sumv[o]; // 此边界区间没有被任何set操作影响
} else { // 递归统计
int M = L + (R-L)/2;
if(qL <= M) query(o*2, L, M);
if(qR > M) query(o*2+1, M+1, R);
}
}
};
const int INF = 1000000000;
IntervalTree tree;
int main() {
freopen("axis.in","r",stdin);
freopen("axis.out","w",stdout);
int n, m;
memset(&tree, 0, sizeof(tree));
memset(tree.setv, -1, sizeof(tree.setv));
scanf("%d%d", &n, &m);
v=1;qL=1;qR=n;
tree.setv[1] = 0;
tree.update(1,1,n);
while(m--) {
scanf("%d%d",&qL, &qR);
v=0;
tree.update(1, 1, n);
_sum = 0;
qL=1;qR=n;
tree.query(1, 1, n);
printf("%d\n", _sum);
}
return 0;
}