码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-08-23 13:36:07      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:math   pac   width   开始   struct   pushd   mem   limit   节点   

卿学姐与基本法

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 - 卿学姐与基本法 (离散化+成段更新+区间求和)

标签:math   pac   width   开始   struct   pushd   mem   limit   节点   

原文地址:http://www.cnblogs.com/Pretty9/p/7417340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!