2016 UESTC Training for Data Structures B - 卿学姐与基本法 自己构建了一个和堆有点像的数据结构

来源:互联网 发布:telnet 端口号不通 编辑:程序博客网 时间:2024/05/14 23:31

B - 卿学姐与基本法

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

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

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

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

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

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

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

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

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

Input

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

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

1N100000000                                                                   

1Q100000                                                                                        

1t2                                         

1LRN                         

Output

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

Sample input and output

Sample InputSample Output
5 31 1 21 4 52 2 4
1

Source

2016 UESTC Training for Data Structures  Problem B


My Solution

对很多个区间进行处理,

这里建一个结构体放存放区间,然后把区间放到vector里,根据左边界排序,

然后逐次进行处理使所以区间变成不相交的区间

一直维护这样的区间

至于说像堆, 是因为:

这个也是延迟操作,在查询单时候才进行维护的

维护时,删除vector的那些元素时令那个元素的 了left 成员为INF,然后sort再pop_back()

查询的时候就vector中的元素一个个查询过去了☺

复杂度 不会算,感觉不是很暴力

#include <iostream>#include <cstdio>#include <vector>#include <algorithm>using namespace std;const int maxq = 100000 +8;const int INF = 0x3f3f3f3f;struct interval{    int l,r;    interval(int x, int y) : l(x), r(y) {}};vector<interval> val;bool cmp(const interval& a, const interval& b){    return a.l < b.l;}int main(){    #ifdef LOCAL    freopen("a.txt", "r", stdin);    #endif // LOCAL    int N, Q;    scanf("%d%d", &N, &Q);    int t, L, R, sz, ans;    while(Q--){        scanf("%d%d%d", &t, &L, &R);        if(t == 1) {            val.push_back(interval(L, R));            sort(val.begin(), val.end(), cmp);            sz = val.size();            for(int i = 0; i < sz; i++){                if(i != sz-1 && val[i].l == val[i+1].l) {val[i].l = INF; val[i+1].r = max(val[i].r, val[i+1].r);}                else if(i != sz-1 && val[i].r >= val[i+1].l) {                    val[i+1].l = val[i].l; val[i].l = INF; val[i+1].r = max(val[i].r, val[i+1].r);                }            }            sort(val.begin(), val.end(), cmp);            while(val[sz-1].l == INF){                val.pop_back();                sz--;            }        }        else{            sz = val.size();ans = R - L + 1;            for(int i = 0; i < sz; i++){                if(val[i].l <= L && val[i].r >= R) {ans = 0; break;}                else if(val[i].l >= L && val[i].r <= R) {ans -= (val[i].r - val[i].l +1);} // 里面,左闭右开                else if(val[i].l >= L && val[i].l <= R && val[i].r >= R) {ans -= (R - val[i].l +1);}                else if(val[i].l <= L && val[i].r >= L && val[i].r <= R) {ans -= (val[i].r - L +1);}            }            printf("%d\n", ans);        }    }    return 0;}

据说也可以用线段树^_^

Thank you!

                                                                                                                                               ------from ProLights

0 0
原创粉丝点击