比赛 [不是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;
}