Bzoj 3781: 小B的询问 莫队,分块,暴力

3781: 小B的询问

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 426  Solved: 284
[Submit][Status][Discuss]

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


 

 

Source

 这道题同 小Z的袜子 。。。
只需要把 加和减 改为 加减 个数的平方 即可。。。
 
代码:
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 #define MAXN 50010
 5 struct node
 6 {
 7     int l,r,id;
 8 }q[MAXN];
 9 LL ans[MAXN];
10 int C[MAXN],pos[MAXN],tot[MAXN];
11 int read()
12 {
13     int s=0,fh=1;char ch=getchar();
14     while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
15     while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
16     return s*fh;
17 }
18 bool cmp(node a,node b)
19 {
20     if(pos[a.l]==pos[b.l])return a.r<b.r;
21     return a.l<b.l;
22 }
23 int main()
24 {
25     int n,m,k,block,i,L,R;
26     LL res;
27     n=read();m=read();k=read();
28     for(i=1;i<=n;i++)C[i]=read();
29     block=(int)sqrt(n);
30     for(i=1;i<=n;i++)pos[i]=(i-1)/block+1;
31     for(i=1;i<=m;i++)
32     {
33         q[i].l=read();q[i].r=read();
34         q[i].id=i;
35     }
36     sort(q+1,q+m+1,cmp);
37     L=1;R=0;res=0;
38     memset(tot,0,sizeof(tot));
39     for(i=1;i<=m;i++)
40     {
41         while(L<q[i].l)
42         {
43             res-=tot[C[L]]*tot[C[L]];
44             tot[C[L]]--;
45             res+=tot[C[L]]*tot[C[L]];
46             L++;
47         }
48         while(L>q[i].l)
49         {
50             L--;
51             res-=tot[C[L]]*tot[C[L]];
52             tot[C[L]]++;
53             res+=tot[C[L]]*tot[C[L]];
54         }
55         while(R<q[i].r)
56         {
57             R++;
58             res-=tot[C[R]]*tot[C[R]];
59             tot[C[R]]++;
60             res+=tot[C[R]]*tot[C[R]];
61         }
62         while(R>q[i].r)
63         {
64             res-=tot[C[R]]*tot[C[R]];
65             tot[C[R]]--;
66             res+=tot[C[R]]*tot[C[R]];
67             R--;
68         }
69         ans[q[i].id]=res;
70     }
71     for(i=1;i<=m;i++)printf("%lld\n",ans[i]);
72     fclose(stdin);
73     fclose(stdout);
74     return 0;
75 }
View Code

 

posted @ 2016-03-15 02:54  微弱的世界  阅读(141)  评论(0编辑  收藏  举报