題意簡述
給定 個區間 ,和 個詢問,每次給你三個整數 ,求被 完全包含且長度 的區間數量。
注:定義一個區間 的長度是 。
,,
思路
如果沒有 的限制,只是要求完全包含的區間數量,可以用兩個樹狀數組,然後計算右端點在 中的數量減去左端點在 中的數量。
然後現在有了 的限制,我們把一個詢問拆成 減去 。然後把詢問和區間都按長度排序,一個一個處理即可。還有就是記錄一下這個答案屬於第幾個詢問,帶正號還是帶負號
( 帶正號, 帶負號,看上面答案是怎麼算的)
然後就做完了。
代碼
{% fold %}
#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{
#define N 1666666
#define F(i,l,r) for(int i=l;i<=r;++i)
#define D(i,r,l) for(int i=r;i>=l;--i)
#define Fs(i,l,r,c) for(int i=l;i<=r;c)
#define Ds(i,r,l,c) for(int i=r;i>=l;c)
#define MEM(x,a) memset(x,a,sizeof(x))
#define FK(x) MEM(x,0)
#define Tra(i,u) for(int i=G.Start(u),v=G.To(i);~i;i=G.Next(i),v=G.To(i))
#define p_b push_back
#define sz(a) ((int)a.size())
#define iter(a,p) (a.begin()+p)
int I()
{
int x=0;char c=getchar();int f=1;
while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return (x=(f==1)?x:-x);
}
void Rd(int cnt,...)
{
va_list args; va_start(args,cnt);
F(i,1,cnt) {int* x=va_arg(args,int*);(*x)=I();}
va_end(args);
}
class BIT
{
public:
int tree[N],len;
void Build(int _len) {FK(tree); len=_len;}
void Add(int pos,int x)
{
while(pos<=len) tree[pos]+=x,pos+=(pos&(-pos));
}
int Query(int pos)
{
int ans=0;
while(pos>0) ans+=tree[pos],pos-=(pos&(-pos));
return ans;
}
}L,R;
struct seg{int l,r;}a[N]; bool operator<(seg a,seg b){return a.r-a.l<b.r-b.l;}
// 給定的線段,按長度排序
struct que{int l,r,k,id,tp;}q[N]; bool operator<(que a,que b){return a.k<b.k;}
// 詢問,也是按長度排序
int n,m; int cnt=0;
void Input()
{
Rd(2,&n,&m);
F(i,1,n) {a[i].l=I(); a[i].r=I();}
F(i,1,m)
{
int l,r,k; Rd(3,&l,&r,&k);
if (k>r-l) continue;
q[++cnt]=(que){l,r,r-l,i,1}; // 記錄編號和符號
q[++cnt]=(que){l,r,k-1,i,-1};
}
}
int ans[N];
void Soviet()
{
sort(a+1,a+n+1); sort(q+1,q+cnt+1);
L.Build(n); R.Build(n); // 兩顆樹狀數組,記錄左端點和右端點
int pos=1;
F(i,1,cnt)
{
while(pos<=n and a[pos].r-a[pos].l<=q[i].k)
{
L.Add(a[pos].l,1); R.Add(a[pos].r,1); ++pos;
}
ans[q[i].id]+=q[i].tp*(R.Query(q[i].r)-L.Query(q[i].l-1));
}
F(i,1,m) printf("%d\n",ans[i]);
}
#define Flan void
Flan IsMyWife()
{
Input();
Soviet();
}
}
int main()
{
Flandre_Scarlet::IsMyWife();
getchar();getchar();
return 0;
}
{% endfold %}