BZOJ - 3781 小B的询问 莫队算法
2017-07-04 17:14
363 查看
大家都很强, 可与之共勉 。
3781: 小B的询问Time Limit: 10 Sec Memory Limit: 128 MB
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
垃圾裸莫队算法
# include <cmath> # include <cstdio> # include <algorithm> const int N = 50005 ; int sq, pos ; struct Query { int l, r, id ; inline short operator < ( const Query& rhs ) const { return ( pos [l] < pos[rhs.l] ) || ( pos [l] == pos[rhs.l] && r < rhs.r ) ; } } q ; int n, m, k ; int a ; int c ; int ans ; int answer ; inline void Update ( int pos, int delta ) { ans += delta * ( c [a [pos]] << 1 ) + 1 ; c [a [pos]] += delta ; } void Solve ( ) { for( register int i = 1, l = 1, r = 0; i <= m ; ++ i ) { while ( r < q [i].r ) Update ( ++ r, 1 ) ; while ( r > q [i].r ) Update ( r --, -1 ) ; while ( l < q [i].l ) Update ( l ++, -1 ) ; while ( l > q [i].l ) Update ( -- l, 1 ) ; answer [q [i].id] = ans ; } } int main ( ) { scanf ( "%d%d%d", & n, & m, & k ) ; for ( int i = 1 ; i <= n ; ++ i ) scanf ( "%d", a + i ) ; sq = sqrt ( n ) ; for ( int i = 1 ; i <= n ; ++ i ) pos [i] = ( i - 1 ) / sq + 1 ; for ( int i = 1 ; i <= m ; ++ i ) { scanf ( "%d%d", &q [i].l, &q [i].r ) ; q [i].id = i ; } std :: sort ( q + 1, q + 1 + m ) ; Solve ( ) ; for ( int i = 1 ; i <= m ; ++ i ) printf ( "%d\n", answer [i] ) ; }
相关文章推荐
- 【莫队算法】bzoj3781 小B的询问
- 【模板】BZOJ 3781: 小B的询问 莫队算法
- bzoj 3781 小B的询问(莫队算法)
- BZOJ 3781 小B的询问 序列莫队算法
- BZOJ 3781: 小B的询问 莫队算法
- 【BZOJ3781】小B的询问【莫队算法】
- bzoj 3781: 小B的询问 莫队算法+分块
- 【bzoj3781】小B的询问 莫队算法
- 【BZOJ】3781: 小B的询问(莫队算法)
- 【P2709】【BZOJ3781】 小B的询问 莫队算法
- BZOJ3781 小B的询问 题解&代码 【附莫队总结】
- 【bzoj3781】小B的询问 莫队
- bzoj3781 小B的询问【莫队】
- 3781: 小B的询问 莫队算法
- 【BZOj 3781】小B的询问 莫队
- bzoj3781: 小B的询问(莫队)
- BZOJ 3781 小B的询问 莫队
- BZOJ_3781_小B的询问_莫队
- [bzoj3781]小B的询问_莫队
- bzoj3781 小B的询问(莫队)