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里面有多少人还没有被普及基本法。
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); }