zoukankan      html  css  js  c++  java
  • [树状数组]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 << '
    ';
                     
                }
            }
        }
         
        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
    */
  • 相关阅读:
    快速模幂
    UPC-2249 曲线分割【递推】
    maven 服务器
    maven repo
    php-fpm sock
    mysql
    go 1
    xdebug
    centos
    win10 2503 2502
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270336.html
Copyright © 2011-2022 走看看