看评论区大佬都水过了,我也先水一下,
复杂度都可以过,可以见得数据之水当然这道题的数据量本身也是符合这个复杂度的,
暴力解法
ps:fill和memset别用得太多,有时候会被卡死
//运行时间:5ms 占用内存:544k
#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define ll int
#define MAX 10005
#define inf 0x3fffff
ll arr[MAX];
int main() {
ll L, M, a, b;
while (cin >> L >> M) {
fill(arr, arr + MAX, 1);
for (int i = 0; i < M; i++) {
cin >> a >> b;
for (int i = a; i <= b; i++)arr[i] = 0;
}
ll res = 0;
for (int i = 0; i <= L; i++)res += arr[i];
cout << res << endl;
}
}
线段树
但是如果 , ?还能水过嘛,显然不能,对于区间查询,区间修改,最好的方式即线段树。这道题的线段树更新也比较简单,具体还是看
#include<iostream>
#include<string>
#include<string.h>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
using namespace std;
#define ll int
#define MAX 10005
#define inf 0x3fffff
ll t[MAX * 4], tag[MAX * 4];
inline ll lc(ll k) { return k << 1; }
inline ll rc(ll k) { return k << 1 | 1; }
void pushUpSum(ll p) { t[p] = t[lc(p)] + t[rc(p)]; }
void build(ll p, ll l, ll r){
if (l == r) { t[p] = 1; return; }
ll mid = (l + r) >> 1;
build(lc(p), l, mid);
build(rc(p), mid + 1, r);
pushUpSum(p);
}
inline void f(ll p, ll l, ll r, ll k) {
tag[p] = k;
t[p] = 0;//这里pushdown是清零操作
if (t[p] < 0)t[p] = 0;
}
inline void pushDown(ll p, ll l, ll r) {
ll mid = (l + r) >> 1;
f(lc(p), l, mid, tag[p]);
f(rc(p), mid + 1, r, tag[p]);
tag[p] = 0;
}
inline void update(ll nl, ll nr, ll l, ll r, ll p, ll k = -1) {
//nl-nr:需要进行-1修改的区间
//l,r,p,k:当前节点所存储的区间以及节点的编号
if (nl <= l && r <= nr) {//需要修改区间包含了当前区间
t[p] = 0; tag[p] = -1; return;//当前区间清零
}
if (tag[p] == -1)pushDown(p, l, r);
ll mid = (l + r) >> 1;
if (nl <= mid)update(nl, nr, l, mid, lc(p));
if (nr > mid)update(nl, nr, mid + 1, r, rc(p));
pushUpSum(p);
}
int main() {
ll L, M, a, b;
while (cin >> L >> M) {
memset(t, 0, sizeof(t));
memset(tag, 0, sizeof(tag));
build(1, 0, L);
for (int i = 0; i < M; i++) {
cin >> a >> b;
update(a, b, 0, L, 1);
}
cout << t[1] << endl;
}
}