Time Limit: 30 Sec
Memory Limit: 512 MB
Description
给你一个长度为
N
N
N的序列
a
i
a_i
ai,
1
≤
i
≤
N
1≤i≤N
1≤i≤N和
q
q
q组询问,每组询问读入
l
1
,
r
1
,
l
2
,
r
2
l_1,r_1,l_2,r_2
l1,r1,l2,r2,需输出
g
e
t
(
l
,
r
,
x
)
get(l,r,x)
get(l,r,x)表示计算区间
[
l
,
r
]
[l,r]
[l,r]中,数字
x
x
x出现了多少次。
Input
第一行,一个数字
N
N
N,表示序列长度。
第二行,
N
N
N个数字,表示
a
1
~
a
N
a_1~a_N
a1~aN
第三行,一个数字
Q
Q
Q,表示询问个数。
第
4
~
Q
+
3
4~Q+3
4~Q+3行,每行四个数字
l
1
,
r
1
,
l
2
,
r
2
l_1,r_1,l_2,r_2
l1,r1,l2,r2,表示询问。
N
,
Q
≤
50000
N,Q≤50000
N,Q≤50000
1
≤
a
i
≤
N
1≤a_i≤N
1≤ai≤N
1
≤
l
1
≤
r
1
≤
N
1≤l_1≤r_1≤N
1≤l1≤r1≤N
1
≤
l
2
≤
r
2
≤
N
1≤l_2≤r_2≤N
1≤l2≤r2≤N
注意:答案有可能超过int的最大值
Output
对于每组询问,输出一行一个数字,表示答案
Sample Input
5
1 1 1 1 1
2
1 2 3 4
1 1 4 4
Sample Output
4
1
题解:
这个玩意儿
我们可以设为
r
e
s
(
l
1
,
r
1
,
l
2
,
r
2
)
res(l_1,r_1,l_2,r_2)
res(l1,r1,l2,r2)
那么
r
e
s
(
l
1
,
r
1
,
l
2
,
r
2
)
res(l_1,r_1,l_2,r_2)
res(l1,r1,l2,r2) =
r
e
s
(
1
,
r
1
,
1
,
r
2
)
res(1,r_1,1,r_2)
res(1,r1,1,r2)-
r
e
s
(
1
,
l
1
−
1
,
1
,
r
2
)
res(1,l_1-1,1,r_2)
res(1,l1−1,1,r2)-
r
e
s
(
1
,
r
1
,
1
,
l
2
−
1
)
res(1,r_1,1,l_2-1)
res(1,r1,1,l2−1)+
r
e
s
(
1
,
l
1
−
1
,
1
,
l
2
−
1
)
res(1,l_1-1,1,l_2-1)
res(1,l1−1,1,l2−1)
好了那么我们把一个询问拆成四个区间了,就可以莫队了。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
int c1[50004],c2[50004];
int n,a[50004],q,cnt;
int belong[50004];
struct ask{
int sit;
int _1,_2,k;
}qu[200004];
ask makeq(int x,int y,int sit,int k){
ask T;
T.sit=sit;T._1=x;T._2=y;T.k=k;
return T;
}
inline bool dex(ask A,ask B){
return belong[A._1]==belong[B._1]?A._2<B._2:belong[A._1]<belong[B._1];
}
ll ans[50004];
void work(){
sort(qu+1,qu+cnt+1,dex);
int o_1=0,o_2=0;
c1[0]=1;
c2[0]=1;
ll val=0;
for(int i=1;i<=cnt;i++){
while(o_1<qu[i]._1){
o_1++;
c1[a[o_1]]++;
val+=c2[a[o_1]];
}
while(o_1>qu[i]._1){
val-=c2[a[o_1]];
c1[a[o_1]]--;
o_1--;
}
while(o_2<qu[i]._2){
o_2++;
c2[a[o_2]]++;
val+=c1[a[o_2]];
}
while(o_2>qu[i]._2){
val-=c1[a[o_2]];
c2[a[o_2]]--;
o_2--;
}
ans[qu[i].sit]+=val*qu[i].k;
}
}
int w33ha(){
cnt=0;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
memset(ans,0,sizeof(ans));
a[0]=0;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
int block=sqrt(1.0*n);
for(int i=1;i<=n;i++)belong[i]=(i-1)/block+1;
scanf("%d",&q);
for(int i=1;i<=q;i++){
int l1,l2,r1,r2;
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
qu[++cnt]=makeq(r1,r2,i,1);
qu[++cnt]=makeq(r1,l2-1,i,-1);
qu[++cnt]=makeq(r2,l1-1,i,-1);
qu[++cnt]=makeq(l1-1,l2-1,i,1);
}
work();
for(int i=1;i<=q;i++)printf("%lld\n",ans[i]);
return 0;
}
int LiangJiaJun(){
while(scanf("%d",&n)!=EOF)w33ha();
return 0;
}