解題思路:
兩棵bit分別存線段的開始點和結束點
兩個數組存開始點和結束點的線段數量
針對每次詢問
用總線段數 - 區間右邊的線段(結尾小於等於x) - 區間左邊的線段(開頭大於等於x) - 當前線段內被完全包含 - 開頭結尾在當前區間內即爲答案
在線更新詢問 複雜度Onlogn
/*
Zeolim - An AC a day keeps the bug away
*/
//#pragma GCC optimize(2)
//#pragma GCC ("-W1,--stack=128000000")
#include <bits/stdc++.h>
using namespace std;
#define mp(x, y) make_pair(x, y)
#define fr(x, y, z) for(int x = y; x < z; ++x)
#define fi(x, n) fill(x, x + n + 10, 0)
typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef std::pair <int, int> pii;
typedef std::vector <int> vi;
//typedef __int128 ill;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll MOD = 386910137;
const ull P = 13331;
const int MAXN = 1e5 + 100;
struct bit
{
ll c[MAXN], N; //c?, N???
bit() {}
bit(int n) { N = n; fill(c, c + N + 1, 0); }
int lowbit(int x) { return x & -x; }
void update(int pos, ll val)
{
for( ;pos <= N; pos += lowbit(pos))
c[pos] += val;
}
ll ask(int pos)
{
ll ret = 0;
for( ;pos; pos -= lowbit(pos))
ret += c[pos];
return ret;
}
};
int t[MAXN], t1[MAXN], t2[MAXN];
int b[MAXN], e[MAXN];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
//freopen("sgtck.out","w",stdout);
//freopen("sgt.in","r",stdin);
int n, q, sum, cntsum;
while( cin >> n >> q )
{
sum = 0;
fi(t, n); fi(t1, n); fi(t2, n);
fi(b, n); fi(e, n);
bit fst(n + 10), lst(n + 10);
int x, y;
while(q--)
{
int opt;
cin >> opt;
if(opt == 1)
{
cin >> x >> y;
++sum;
fst.update(x, 1);
lst.update(y, 1);
if(x == y)
++t[x];
else
++b[x], ++e[y];
}
else
{
cin >> x >> y;
int ans = sum;
if(x == y)
{
ans -= lst.ask(x - 1);
ans -= (fst.ask(n) - fst.ask(y));
}
else if(x + 1 == y)
{
ans -= lst.ask(x);
ans -= (fst.ask(n) - fst.ask(y - 1));
}
else
{
ans -= lst.ask(x);
ans -= (fst.ask(n) - fst.ask(y - 1));
ans -= t[x + 1];
ans -= b[x + 1];
ans -= e[x + 1];
}
cout << ans << '\n';
}
}
}
return 0;
}
/*
5 9
1 1 3
1 2 4
1 3 5
1 2 2
1 3 3
1 4 4
1 3 4
1 4 5
2 3 3
*/