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

卿学姐与基本法

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

Submit Status

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

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

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

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

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

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

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

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

Input

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

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

1≤N≤1000000001≤N≤100000000

1≤Q≤1000001≤Q≤100000

1≤t≤21≤t≤2

1≤L≤R≤N1≤L≤R≤N

Output

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

Sample input and output

Sample Input Sample 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);
}
时间: 2024-12-16 10:28:17

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

NYOJ 1068 ST(线段树之 成段更新+区间求和)

ST 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 "麻雀"lengdan用随机数生成了后台数据,但是笨笨的他被妹纸的问题给难住了... 已知lengdan生成了N(1=<N<=10005)个随机整数,妹子对这些数可能有以下几种操作或询问: 1,A a b c 表示给区间a到b内每个数都加上c: 2,S a b  表示输出区间a到b内的和: 3,Q a b 表示区间a到b内的奇数的个数: 为了使妹纸不口渴,所以我们决定妹纸的询问次数少一点,即

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

A - 卿学姐与公主 Time Limit: 2000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Status 某日,百无聊赖的卿学姐打开了某11区的某魔幻游戏 在这个魔幻的游戏里,生活着一个美丽的公主,但现在公主被关押在了魔王的城堡中. 英勇的卿学姐拔出利刃冲向了拯救公主的道路. 走过了荒野,翻越了高山,跨过了大洋,卿学姐来到了魔王的第一道城关. 在这个城关面前的是魔王的精锐部队,这些士兵

CDOJ 1325 卿学姐与基本法 (离散化+区间修改)

题意 初始时所有人姿势水平都比较低,然后卿神去给一个区间的人们普及基本法,然后还可以查询某个区间还有多少个人没有被普及基本法. 思路 因为数据比较大所以我们先离散化一下,注意离散化的小bug(参考poj上的那个海报覆盖问题). 刚开始全部初始化为0然后update为1,在更新的时候不是很好处理,还是用1表示没学,更新的时候置零比较好处理. 代码 #include <stdio.h> #include <string.h> #include <iostream> #inc

poj 2777 Count Color (成段更新+区间求和)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36646   Accepted: 11053 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

(线段树成段更新+区间求和) poj 3468

D - A Simple Problem with Integers Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3468 Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One typ

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

卿学姐与基本法 (线段树+离散化)

“做专题也要按照基本法” 离开了诡异的村庄,卿学姐来到了威廉·圣·乱七八糟王国,这里的国王咸鱼王是个智障. 国家涣散,盗贼四起,民不聊生. 见到这样的景象,卿学姐不禁潸然泪下,“悠悠苍天,奈何苦了苍生”. 自幼学习基本法的卿学姐决定向整个国家普及基本法,改善国家法度. 在这个国家总共有NN个人,每个人都有一个编号,编号从1开始. 由于整个国家的人实在是太多了,卿学姐每次只能对一个连续区间的编号的人普及基本法. 同时卿学姐还想知道在某个时刻某个区间还有多少人没有被普及基本法. Input 第一行两

HDU 3397 Sequence operation(线段树&#183;成段更新&#183;区间合并&#183;混合操作)

题意  给你一个只有0, 1的数组  有这些操作 0. 将[a, b]区间的所有数都改为0 1. 将[a, b]区间的所有数都改为1 2. 将[a, b]区间的所有数都取反 即与1异或 3. 输出区间[a, b]中1的个数  即所有数的和 4. 输出区间[a, b]中最大连续1的长度 对于所有的3, 4操作输出对应的答案 单个的操作都很简单  但搞在一起就有点恶心了  还好数组里的数只有0和1 线段树维护9个值 对应区间0, 1的最大长度len[i]  对应区间左端点为起点的最大0, 1长度ll

poj 3468 线段树 成段增减 区间求和

题意:Q是询问区间和,C是在区间内每个节点加上一个值 Sample Input 10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4Sample Output 455915 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6