B - 卿学姐与基本法 (离散化+成段更新+区间求和)

Posted Pretty9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B - 卿学姐与基本法 (离散化+成段更新+区间求和)相关的知识,希望对你有一定的参考价值。

卿学姐与基本法

Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

“做专题也要按照基本法”

离开了诡异的村庄,卿学姐来到了威廉·圣·乱七八糟王国,这里的国王咸鱼王是个智障。

国家涣散,盗贼四起,民不聊生。

见到这样的景象,卿学姐不禁潸然泪下,“悠悠苍天,奈何苦了苍生”。

自幼学习基本法的卿学姐决定向整个国家普及基本法,改善国家法度。

在这个国家总共有NN个人,每个人都有一个编号,编号从1开始。

由于整个国家的人实在是太多了,卿学姐每次只能对一个连续区间的编号的人普及基本法。

同时卿学姐还想知道在某个时刻某个区间还有多少人没有被普及基本法。

Input

第一行两个整数N,QN,Q,表示总共有NN个人,并且有QQ次事件。

接下来QQ行,每行三个整数t,L,Rt,L,R。如果tt是11,代表在这时,卿学姐向闭区间L,RL,R的人普及基本法。如果tt是22,代表在这时,卿学姐想知道闭区间L,RL,R里面有多少人还没有被普及基本法。

1N1000000001≤N≤100000000

1Q1000001≤Q≤100000

1t21≤t≤2

1LRN1≤L≤R≤N

Output

输出每个卿学姐想知道的答案

Sample input and output

Sample InputSample Output
5 3
1 1 2
1 4 5
2 2 4
1

emmmm......做了这题之后感觉自己学到了很多有趣的东西,WA了很多次,看数据范围就知道要离散化,在一开始的时候,建树直接给节点赋值1。。。然后肯定WA。。。因为我把区间搞丢了,要离散成右闭左开的区间。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<map>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1|1
const int N = 100000 + 5;
int sum[N << 4], col[N << 4];

vector<int> v;
map<int, int> dic;

struct node{
    int t, l, r;
}M[N];

void PushUP(int rt){
    sum[rt] = sum[rt << 1] + sum[rt << 1|1];
}

void PushDown(int rt){
    if(col[rt]){
        col[rt << 1] = col[rt << 1|1] = 1;
        sum[rt << 1] = sum[rt << 1|1]  = 0;
        col[rt] = 0;
    }
}

void Build(int l, int r, int rt){
    col[rt] = 0;
    if(l == r){
        sum[rt] = v[l] - v[l - 1];
        return;
    }
    int m = (l + r) >> 1;
    Build(lson);
    Build(rson);
    PushUP(rt);
}

void Updata(int L, int R, int l, int r, int rt){
    if(L <= l && r <= R){
        col[rt] = 1;
        sum[rt] = 0;
        return;
    }
    PushDown(rt);
    int m = (l + r) >> 1;
    if(L <= m) Updata(L, R, lson);
    if(R > m) Updata(L, R, rson);
    PushUP(rt);
}

int Query(int L, int R, int l, int r, int rt){
    if(L <= l && r <= R){
        return sum[rt];
    }
    PushDown(rt);
    int m = (l + r) >> 1;
    int ret = 0;
    if(L <= m) ret += Query(L, R, lson);
    if(R > m) ret += Query(L, R, rson);
    return ret;
}

void Work(int n, int m){
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    int k = v.size();
    for(int i = 1; i < k; i++)
        dic[v[i]] = i;

    Build(1, k, 1);
    for(int i = 1; i <= m; i++){
        if(M[i].t == 1) Updata(dic[M[i].l], dic[M[i].r], 1, k, 1);
        else printf("%d\n", Query(dic[M[i].l], dic[M[i].r], 1, k, 1));
    }
}
int main(){
    int n, m;
    scanf("%d %d", &n, &m);
    v.push_back(0);
    for(int i = 1; i <= m; i++){
        scanf("%d %d %d", &M[i].t, &M[i].l, &M[i].r);
        v.push_back(M[i].l); v.push_back(M[i].r);
        v.push_back(M[i].l + 1);
    }
    Work(n, m);
}

 

以上是关于B - 卿学姐与基本法 (离散化+成段更新+区间求和)的主要内容,如果未能解决你的问题,请参考以下文章

A - 卿学姐与公主(线段树+单点更新+区间极值)

UESTC - 1324 卿学姐与公主

卿学姐与魔法

卿学姐与公主

卿学姐与魔法(优先队列)

卿学姐与公主 UESTC - 1324 分块模板题