注:离散化和离线化其实没什么关系,离线对应的是在线算法。
- 例题:求 i ∈ [ L , R ] , F i b [ i ] % 1000007 ∈ [ l , r ] i ∈ [ L , R ] , F i b [ i ] i\in[L,R],Fib[i]\%1000007\in[l, r]i∈[L,R],Fib[i]%1000007∈[l,r] i∈[L,R],Fib[i]%1000007∈[l,r]i∈[L,R],Fib[i]的个数。
- 代码
#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;
}