5016: [Snoi2017]一个简单的询问
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 326 Solved: 221
[ Submit][ Status][ Discuss]
Description
给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出

get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次。
Input
第一行,一个数字N,表示序列长度。
第二行,N个数字,表示a1~aN
第三行,一个数字Q,表示询问个数。
第4~Q+3行,每行四个数字l1,r1,l2,r2,表示询问。
N,Q≤50000
N1≤ai≤N
1≤l1≤r1≤N
1≤l2≤r2≤N
注意:答案有可能超过int的最大值
Output
对于每组询问,输出一行一个数字,表示答案
Sample Input
5
1 1 1 1 1
2
1 2 3 4
1 1 4 4
1 1 1 1 1
2
1 2 3 4
1 1 4 4
Sample Output
4
1
1
HINT
Source
#include<queue>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 2147483647;
const int maxn = 200010;
struct data{
int id,l,r,be,f;
}q[maxn];
int n,m,len,tot,a[maxn];
int cnt[maxn][2];
LL now,ans[maxn];
inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}
inline void modify(int l,int r,int d,int f)
{
for (int i = l; i <= r; i++)
{
if (i == 0) continue;
now += f * cnt[a[i]][d ^ 1];
cnt[a[i]][d] += f;
}
}
inline int cmp(data a,data b)
{
return (a.be < b.be) || (a.be == b.be && a.r < b.r);
}
int main()
{
#ifdef AMC
freopen("AMC1.txt","r",stdin);
#endif
n = getint();
for (int i = 1; i <= n; i++)
a[i] = getint();
len = sqrt(n);
m = getint();
for (int i = 1; i <= m; i++)
{
int l1 = getint(),r1 = getint(),l2 = getint(),r2 = getint();
q[++tot] = (data){i,r1,r2,ceil(1.0 * r1 / len),1};
q[++tot] = (data){i,r1,l2 - 1,ceil(1.0 * r1 / len),-1};
q[++tot] = (data){i,l1 - 1,r2,ceil(1.0 * (l1 - 1) / len),-1};
q[++tot] = (data){i,l1 - 1,l2 - 1,ceil(1.0 * (l1 - 1) / len),1};
}
sort(q + 1,q + tot + 1,cmp);
q[0].r = -1;
for (int i = 1; i <= tot; i++)
{
int test;
if (i == 5)
test = 1;
if (q[i - 1].l < q[i].l)
modify(q[i - 1].l + 1,q[i].l,0,1);
if (q[i].l < q[i - 1].l)
modify(q[i].l + 1,q[i - 1].l,0,-1);
if (q[i - 1].r < q[i].r)
modify(q[i - 1].r + 1,q[i].r,1,1);
if (q[i].r < q[i - 1].r)
modify(q[i].r + 1,q[i - 1].r,1,-1);
ans[q[i].id] += q[i].f * now;
}
for (int i = 1; i <= m; i++)
printf("%lld\n",ans[i]);
return 0;
}