签到题模拟做法
和我一样一开始照着出题人描述补函数的举起爪子,我最后TLE吐了,才发现,如果按照他思路,时间爆炸了……
直接改掉函数,模拟就行了,其实也可以用线段树,当然更快,模拟更轻松一点就是了。)看来被set大常数卡的不轻,当然也感谢出题人仁慈没给极限数据……
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
typedef long long ll;
int a[maxn];
int opt, x, y;
set<pair<int, int> >P;
int main(){
int n, L;
cin >> n >> L;
int ans = 0;
while (n--){
cin >> opt >> x >> y;
if (opt == 1){
if (P.find(make_pair(x, y)) != P.end()) continue;
P.insert(make_pair(x, y));
for (int i = x; i <= y; i++){
a[i]++;
if (a[i] == 1) ans++;
}
}
else if (opt == 2){
if (P.find(make_pair(x, y)) == P.end()) continue;
P.erase(make_pair(x, y));
for (int i = x; i <= y; i++){
a[i]--;
if (a[i] == 0) ans--;
}
}
else{
cout << ans << endl;
}
}
return 0;
}
E正解、线段树写法
区间更新,区间查询,如果区间值大于1,正解求区间长度即可。否则就要去左右子树累加区间值大于1的区间长度,线段树操作
#include <bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;
inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; }
const int MAXN = 100010;
struct Node {
int l, r;
//ll lazy;
ll sum;
} segTree[MAXN << 2];
void build(int i, int l, int r) {
segTree[i].l = l;
segTree[i].r = r;
if (l == r) {
//scanf("%lld", &segTree[i].sum);
return;
}
int mid = l + r >> 1;
build(i << 1, l, mid);
build(i << 1 | 1, mid + 1, r);
//segTree[i].sum = segTree[i << 1].sum + segTree[i << 1 | 1].sum;
}
void push_up(int i) {
ll tmp = min(segTree[i << 1].sum, segTree[i << 1 | 1].sum);
segTree[i].sum += tmp;
segTree[i << 1].sum -= tmp;
segTree[i << 1 | 1].sum -= tmp;
}
void push_down(int i) {
if (segTree[i].sum) {
segTree[i << 1].sum += segTree[i].sum;
segTree[i << 1 | 1].sum += segTree[i].sum;
segTree[i].sum = 0;
}
}
void add(int i, int l, int r, ll v) {
if (segTree[i].l >= l && segTree[i].r <= r) {
segTree[i].sum += v;
return;
}
push_down(i);
int mid = segTree[i].l + segTree[i].r >> 1;
if (mid >= l) add(i << 1, l, r, v);
if (mid < r) add(i << 1 | 1, l, r, v);
push_up(i);
}
ll query(int i, int l, int r) {
ll res = 0;
if (segTree[i].l >= l && segTree[i].r <= r)
if (segTree[i].sum > 0)
res += r - l + 1;
else if (l != r) {
int mid = segTree[i].l + segTree[i].r >> 1;
push_down(i);
res += query(i << 1, l, mid);
res += query(i << 1 | 1, mid + 1, r);
push_up(i);
}
return res;
}
int main() {
int n, m, op;
scanf("%d%d", &n, &m);
build(1, 1, m);
int l, r;
while (n--) {
op = read(), l = read(), r = read();
if (op == 1)
add(1, l, r, 1);
else if (op == 2)
add(1, l, r, -1);
else
printf("%lld\n", query(1, 1, m));
}
return 0;
} 
京公网安备 11010502036488号