[樹狀數組]H千萬別用樹套樹

解題思路:

兩棵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
*/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章