BZOJ 3781
Description
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。小B请你帮助他回答询问。
Input
第一行,三个整数N、M、K。
第二行,N个整数,表示小B的序列。
接下来的M行,每行两个整数L、R。
Output
M行,每行一个整数,其中第i行的整数表示第i个询问的答案。
Sample Input
6 4 3
1 3 2 1 1 3
1 4
2 6
3 5
5 6
Sample Output
6
9
5
2
HINT
对于全部的数据,1<=N、M、K<=50000
跟小z的袜子差不多算模板题吧,因为没修改
CODE 1 #include<stdio.h>
2 #include<algorithm>
3 #include<string.h>
4 #include<math.h>
5 #include<string>
6 #include<iostream>
7 using namespace std;
8 typedef long long ll;
9
10 #define N 1000002
11 int a[N],pos[N],block;
12 int n,m,k;
13 ll ans=0;
14 ll tmp[N];
15 struct node
16 {
17 int l,r,id;
18 ll ans;
19 }q[N];
20 int cmp(node a,node b)
21 {
22 if (pos[a.l]==pos[b.l]) return a.r<b.r;
23 return pos[a.l]<pos[b.l];
24 }
25 int cmpid(node a,node b)
26 {
27 return a.id<b.id;
28 }
29 void solve()
30 {
31 int l=1,r=0;//注意l=1,r=0
32 ll ans=0;
33 for (int i=1;i<=m;i++)
34 {
35 while (r<q[i].r)
36 {
37 r++;
38 ans-=tmp[a[r]]*tmp[a[r]];
39 tmp[a[r]]++;
40 ans+=tmp[a[r]]*tmp[a[r]];
41 }
42 while (l>q[i].l)
43 {
44 l--;
45 ans-=tmp[a[l]]*tmp[a[l]];
46 tmp[a[l]]++;
47 ans+=tmp[a[l]]*tmp[a[l]];
48 }
49
50 while (l<q[i].l)
51 {
52 ans-=tmp[a[l]]*tmp[a[l]];
53 tmp[a[l]]--;
54 ans+=tmp[a[l]]*tmp[a[l]];
55 l++;
56 }
57
58 while (r>q[i].r)
59 {
60
61 ans-=tmp[a[r]]*tmp[a[r]];
62 tmp[a[r]]--;
63 ans+=tmp[a[r]]*tmp[a[r]];
64 r--;
65 }
66 q[i].ans=ans;
67 }
68 }
69
70 int main()
71 {
72 scanf("%d%d%d",&n,&m,&k);
73 for (int i=1;i<=n;i++)
74 scanf("%d",&a[i]);
75 block=sqrt(n);
76 for (int i=1;i<=n;i++)
77 pos[i]=(i-1)/block+1;
78 for (int i=1;i<=m;i++)
79 scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
80
81 sort(q+1,q+m+1,cmp);
82 solve();
83 sort(q+1,q+m+1,cmpid);
84 for (int i=1;i<=m;i++)
85 printf("%d\n",q[i].ans);
86
87 return 0;
3 #include<string.h>
4 #include<math.h>
5 #include<string>
6 #include<iostream>
7 using namespace std;
8 typedef long long ll;
9
10 #define N 1000002
11 int a[N],pos[N],block;
12 int n,m,k;
13 ll ans=0;
14 ll tmp[N];
15 struct node
16 {
17 int l,r,id;
18 ll ans;
19 }q[N];
20 int cmp(node a,node b)
21 {
22 if (pos[a.l]==pos[b.l]) return a.r<b.r;
23 return pos[a.l]<pos[b.l];
24 }
25 int cmpid(node a,node b)
26 {
27 return a.id<b.id;
28 }
29 void solve()
30 {
31 int l=1,r=0;//注意l=1,r=0
32 ll ans=0;
33 for (int i=1;i<=m;i++)
34 {
35 while (r<q[i].r)
36 {
37 r++;
38 ans-=tmp[a[r]]*tmp[a[r]];
39 tmp[a[r]]++;
40 ans+=tmp[a[r]]*tmp[a[r]];
41 }
42 while (l>q[i].l)
43 {
44 l--;
45 ans-=tmp[a[l]]*tmp[a[l]];
46 tmp[a[l]]++;
47 ans+=tmp[a[l]]*tmp[a[l]];
48 }
49
50 while (l<q[i].l)
51 {
52 ans-=tmp[a[l]]*tmp[a[l]];
53 tmp[a[l]]--;
54 ans+=tmp[a[l]]*tmp[a[l]];
55 l++;
56 }
57
58 while (r>q[i].r)
59 {
60
61 ans-=tmp[a[r]]*tmp[a[r]];
62 tmp[a[r]]--;
63 ans+=tmp[a[r]]*tmp[a[r]];
64 r--;
65 }
66 q[i].ans=ans;
67 }
68 }
69
70 int main()
71 {
72 scanf("%d%d%d",&n,&m,&k);
73 for (int i=1;i<=n;i++)
74 scanf("%d",&a[i]);
75 block=sqrt(n);
76 for (int i=1;i<=n;i++)
77 pos[i]=(i-1)/block+1;
78 for (int i=1;i<=m;i++)
79 scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
80
81 sort(q+1,q+m+1,cmp);
82 solve();
83 sort(q+1,q+m+1,cmpid);
84 for (int i=1;i<=m;i++)
85 printf("%d\n",q[i].ans);
86
87 return 0;
88 }
随性Code