题意:
n个数,一个k,m个询问,每个询问有[l1,r1] ,[l2,r2]两个区间,[l1,r1]中取x ,[l2,r2]中取y,使得x+y=k
(l1 <= r1 < l2 <= r2)
分析:
根据容斥,F(l1,r1,l2,r2)=f(l1,r2)-f(r1+1,r2)-f(l1,l2-1)+f(r1+1,l2-1)。 记录下加减。
这样可以把两个不相干的区间分成四个区间,然后就可以用莫队了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<vector>
#include<cctype>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<iomanip>
#include<sstream>
#include<limits>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 2e5+10;
const ll MOD = 1000000007;
const double EPS = 1e-10;
const double Pi = acos(-1.0);
struct Node{
int l,r,id,x,f;
}Q[maxn];
ll ans[maxn];
int a[maxn],num[maxn];
int unit;
bool cmp(Node a,Node b)
{
if (a.x != b.x) return a.x < b.x;
else return a.r<b.r;
}
int main(){
#ifdef LOCAL
freopen("C:\\Users\\lanjiaming\\Desktop\\acm\\in.txt","r",stdin);
//freopen("output.txt","w",stdout);
#endif
//ios_base::sync_with_stdio(0);
int n,m,k;
while(scanf("%d%d",&n,&k) != EOF)
{
for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
unit = (int)sqrt(n);
scanf("%d",&m);
for(int i = 0; i < m; i++)
{
int l1,l2,r1,r2;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
Q[i*4].l=l1; Q[i*4].r=r2; Q[i*4].id=i; Q[i*4].f=1;
Q[i*4+1].l=l1; Q[i*4+1].r=l2-1;Q[i*4+1].id=i;Q[i*4+1].f=-1;
Q[i*4+2].l=r1+1;Q[i*4+2].r=r2; Q[i*4+2].id=i;Q[i*4+2].f=-1;
Q[i*4+3].l=r1+1;Q[i*4+3].r=l2-1;Q[i*4+3].id=i;Q[i*4+3].f=1;
Q[i*4].x = (Q[i*4].l-1) / unit + 1;
Q[i*4+1].x = (Q[i*4+1].l-1) / unit + 1;
Q[i*4+2].x = (Q[i*4+2].l-1) / unit + 1;
Q[i*4+3].x = (Q[i*4+3].l-1) / unit + 1;
}
sort(Q,Q+m*4,cmp);
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
int L = Q[0].l, R = Q[0].l-1;
ll temp = 0;
for(int i = 0;i < m*4;i++)
{
while(R < Q[i].r)
{
R++;
if (k - a[R] > 0 && k - a[R] <= n) temp += num[k-a[R]];
num[a[R]]++;
}
while(R > Q[i].r)
{
num[a[R]]--;
if (k - a[R] > 0 && k - a[R] <= n) temp -= num[k-a[R]];
R--;
}
while(L < Q[i].l)
{
num[a[L]]--;
if (k - a[L] > 0 && k - a[L] <= n) temp -= num[k-a[L]];
L++;
}
while(L > Q[i].l)
{
L--;
if (k - a[L] > 0 && k - a[L] <= n) temp += num[k-a[L]];
num[a[L]]++;
}
ans[Q[i].id] += temp*Q[i].f;
}
for(int i = 0; i < m; i++) printf("%lld\n",ans[i]);
}
return 0;
}