• 题意
    • 编号为0~N-1的灯泡,初始都是关闭的, M次操作
    • 每次操作把一个区间的灯泡就像翻转,问最后打开的灯有多少个。
    • N<=1e6, M<=1e3
    • T<=1e3组样例
  • 题解
    • 看到题目直接写了一发树状数组,T了
    • 实际上我们看到M<=1e3,且唯一一次询问在所有翻转操作之后
    • 所以直接排序(相当于离散化)+ 差分即可
  • 代码
    • #include <bits/stdc++.h>
      using namespace std;
      
      const int MAXN = 2010;
      pair<int, int> p[MAXN];
      int main() {
        int T;
        int iCase = 0;
        int N, M;
        scanf("%d", &T);
        while (T--) {
          iCase++;
          scanf("%d%d", &N, &M);
          int tot = 0;
          while(M--) {
            int l, r;
            scanf("%d%d", &l, &r);
            p[tot++] = make_pair(l, 1);
            p[tot++] = make_pair(r+1, -1);
          }
          sort(p, p+tot);
          int now = 0;
          int ans = 0;
          int sum = 0;
          for (int i = 0; i < tot; i++) {
            if (now != p[i].first) {
              if (sum&1) ans += p[i].first - now;
              now = p[i].first;
            }
            sum += p[i].second;
          }
          if (sum &1) ans += N - now;
          printf("Case #%d: %d\n", iCase, ans);
        }
        return 0;
      }

发表评论

邮箱地址不会被公开。 必填项已用*标注