3781: 小B的询问
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1039 Solved: 697
[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
1 3 2 1 1 3
1 4
2 6
3 5
5 6
Sample Output
6
9
5
2
9
5
2
HINT
对于全部的数据,1<=N、M、K<=50000
Source
哈哈哈也许是上一题搞的时间太长了,老天眷顾了我一道水题,虽然是道权限题,虽然一开始由于轻敌把题目看错了 _(:зゝ∠)_ 然而还是很快就水出来咯~
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=5e4+5; 5 int n,m; 6 LL a[MAX],b[MAX],pos[MAX],ans,an[MAX],bas; 7 struct Node{ 8 int id; 9 int l,r; 10 bool operator < (const Node &tt) const { 11 if (pos[l]!=pos[tt.l]) 12 return pos[l]<pos[tt.l]; 13 return r<tt.r; 14 } 15 }que[MAX]; 16 inline int read(){ 17 int an=0,x=1;char c=getchar(); 18 while (c<'0' || c>'9') {if (c=='-') x=-1;c=getchar();} 19 while (c>='0' && c<='9') {an=an*10+c-'0';c=getchar();} 20 return an*x; 21 } 22 void update(int x,int y){ 23 ans-=b[a[x]]*b[a[x]]; 24 b[a[x]]+=y; 25 ans+=b[a[x]]*b[a[x]]; 26 } 27 int main(){ 28 freopen ("ask.in","r",stdin); 29 freopen ("ask.out","w",stdout); 30 int i,j; 31 n=read();m=read();read();bas=(LL)sqrt(n*1.0); 32 memset(b,0,sizeof(b)); 33 for (i=1;i<=n;i++) a[i]=read(),pos[i]=(i-1)/bas+1; 34 for (i=1;i<=m;i++){ 35 que[i].id=i; 36 que[i].l=read();que[i].r=read(); 37 } 38 sort(que+1,que+m+1); 39 int L=1,R=0; 40 for (i=1;i<=m;i++){ 41 while (R<que[i].r){R++;update(R,1);} 42 while (L>que[i].l){L--;update(L,1);} 43 while (R>que[i].r){update(R,-1);R--;} 44 while (L<que[i].l){update(L,-1);L++;} 45 an[que[i].id]=ans; 46 } 47 for (i=1;i<=m;i++) 48 printf("%d\n",an[i]); 49 return 0; 50 }
未来是什么样,未来会发生什么,谁也不知道。
但是我知道,
起码从今天开始努力,
肯定比从明天开始努力,
要快一天实现梦想。
千里之行,始于足下! ——《那年那兔那些事儿》