離散化和離線化初步(10-5講課)

注:離散化和離線化其實沒什麼關係,離線對應的是在線算法。

  • 例題:求i[L,R],Fib[i]%1000007[l,r]i[L,R],Fib[i]i\in[L,R],Fib[i]\%1000007\in[l, r]i∈[L,R],Fib[i]%1000007∈[l,r]的個數。
  • 代碼
#include<bits/stdc++.h>
using namespace std;

#define lowbit(x) (x&(-x))
const int mx = 1e6+7;
const int mod = 1e6+7;
struct TreeArray ///樹狀數組部分
{
    int tree[mx + 10], len;

    void clear(int n)
    {
        len = n;
        for(int i=0; i<=len; i++)
            tree[i] = 0;
    }

    void add(int index, int value)
    {
        while (index <= len)
        {
            tree[index] += value;
            index += lowbit(index);
        }
    }

    int query(int index)
    {
        int ans = 0;
        while(index)
        {
            ans += tree[index];
            index -= lowbit(index);
        }
        return ans;
    }

    int query(int l, int r)
    {
        return query(r) - query(l - 1);
    }
} TA;

pair<int, int> range[10010];
int ans[10010];
vector<pair<int, int> > ve[mx];
int F[100010] = {0, 1};

int main()
{
    TA.clear(mod);     ///把容量爲mod的tree數組賦爲0
    int T;
    scanf("%d", &T);
    for(int i=0; i<T; i++)
    {
        int L, R, l, r;
        scanf("%d%d%d%d", &L, &R, &l, &r);
        range[i] = {l, r};     ///用range記錄每組查詢的比較範圍
        ve[L-1].push_back({i, -1}), ve[R].push_back({i, 1});   ///ve記錄每組查詢的範圍
    }
    TA.add(1, 1);
    for(int i=2; i<=100000; i++)
    {
        F[i] = (F[i-1] + F[i-2]) % mod;
        TA.add(F[i], 1);
        for(auto c : ve[i])
            ans[c.first] += c.second * TA.query(range[c.first].first, range[c.first].second);
    }
    for(int i=0; i<T; i++)
        printf("%d\n", ans[i]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章