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;

88 } 

 

posted on 2015-09-05 02:18  forgot93  阅读(172)  评论(0编辑  收藏  举报

导航