【HDU】5213 Lucky 【分块(在线算法)】
来源:互联网 发布:thinksns app源码 编辑:程序博客网 时间:2024/06/08 18:17
传送门:【HDU】5213 Lucky
题目分析:
我来说一下这题的在线做法。
首先我们将区间分成
接下来,对于每组询问,我们考虑一个区间,这个区间内完整的块最多
设
令
这样我们就做到了在线处理了。
my code:
#include <stdio.h>#include <string.h>#include <set>#include <map>#include <math.h>#include <algorithm>using namespace std ;typedef long long LL ;#define clr( a , x ) memset ( a , x , sizeof a )#define cpy( a , x ) memcpy ( a , x , sizeof a )const int MAXN = 30005 ;const int SQR = 300 ;int n , m , K , sqr ;int a[MAXN] ;int f[SQR][SQR] ;int g[SQR][MAXN] ;int vis[MAXN] , Time ;int cnt[MAXN] , cnt2[MAXN] ;void solve () { int l1 , l2 , r1 , r2 ; clr ( f , 0 ) ; clr ( a , 0 ) ; clr ( g , 0 ) ; sqr = sqrt ( 1.0 * n ) ; for ( int i = 1 ; i <= n ; ++ i ) scanf ( "%d" , &a[i] ) ; for ( int i = 1 , x = 1 ; i <= n ; i += sqr , ++ x ) { for ( int j = i ; j <= min ( i + sqr - 1 , n ) ; ++ j ) ++ g[x][a[j]] ; for ( int j = 1 ; j <= n ; ++ j ) g[x][j] += g[x - 1][j] ; for ( int j = 1 , y = 1 ; j <= n ; j += sqr , ++ y ) { ++ Time ; for ( int k = j ; k <= min ( j + sqr - 1 , n ) ; ++ k ) { if ( vis[a[k]] == Time ) ++ cnt[a[k]] ; else { vis[a[k]] = Time ; cnt[a[k]] = 1 ; } } for ( int k = i ; k <= min ( i + sqr - 1 , n ) ; ++ k ) { if ( K - a[k] > 0 && K - a[k] <= n && vis[K - a[k]] == Time ) { f[x][y] += cnt[K - a[k]] ; } } } for ( int y = 1 ; y < SQR ; ++ y ) f[x][y] += f[x][y - 1] ; } scanf ( "%d" , &m ) ; for ( int o = 1 ; o <= m ; ++ o ) { scanf ( "%d%d%d%d" , &l1 , &r1 , &l2 , &r2 ) ; int ans = 0 ; int L1 = ( l1 - 1 ) / sqr + 2 ; int R1 = ( r1 - 1 ) / sqr ; int L2 = ( l2 - 1 ) / sqr + 2 ; int R2 = ( r2 - 1 ) / sqr ; if ( L1 <= R1 && L2 <= R2 ) { for ( int i = L1 ; i <= R1 ; ++ i ) { ans += f[i][R2] - f[i][L2 - 1] ; } } ++ Time ; int t = min ( r2 , ( L2 - 1 ) * sqr ) ; for ( int i = l2 ; i <= t ; ++ i ) { int tt = K - a[i] ; if ( tt > 0 && tt <= n & R1 >= L1 ) ans += g[R1][tt] - g[L1 - 1][tt] ; if ( vis[a[i]] == Time ) ++ cnt2[a[i]] ; else { vis[a[i]] = Time ; cnt2[a[i]] = 1 ; } } if ( t != r2 ) { for ( int i = R2 * sqr + 1 ; i <= r2 ; ++ i ) { int tt = K - a[i] ; if ( tt > 0 && tt <= n && R1 >= L1 ) ans += g[R1][tt] - g[L1 - 1][tt] ; if ( vis[a[i]] == Time ) ++ cnt2[a[i]] ; else { vis[a[i]] = Time ; cnt2[a[i]] = 1 ; } } } t = min ( r1 , ( L1 - 1 ) * sqr ) ; for ( int i = l1 ; i <= t ; ++ i ) { int tt = K - a[i] ; if ( tt > 0 && tt <= n && R2 >= L2 ) ans += g[R2][tt] - g[L2 - 1][tt] ; if ( tt > 0 && tt <= n && vis[tt] == Time ) ans += cnt2[tt] ; } if ( t != r1 ) { for ( int i = R1 * sqr + 1 ; i <= r1 ; ++ i ) { int tt = K - a[i] ; if ( tt > 0 && tt <= n && R2 >= L2 ) ans += g[R2][tt] - g[L2 - 1][tt] ; if ( tt > 0 && tt <= n && vis[tt] == Time ) ans += cnt2[tt] ; } } printf ( "%d\n" , ans ) ; }}int main () { Time = 0 ; clr ( vis , 0 ) ; while ( ~scanf ( "%d%d" , &n , &K ) ) solve () ; return 0 ;}
0 0
- 【HDU】5213 Lucky 【分块(在线算法)】
- hdu 5213 Lucky(莫队算法分块+容斥定理)
- 【分块】 HDOJ 5213 Lucky
- HDU 5213 Lucky(容斥原理+莫队算法)
- HDOJ 5213 Lucky(分块+莫队+容斥原理)
- Lucky - HDU 5213 莫队算法
- 2016-scut-H. Lucky Array(分块)
- Codeforces 122 C. Lucky Sum(分块)
- hdu 5213 Lucky(容斥+莫队)
- HDU 5213 Lucky(莫队+容斥)
- hdu 5213 Lucky && 莫队算法的理解
- lucky number(hdu 3346)
- HDU - 5665 Lucky (技巧)
- hdu 4638 Group(莫队算法+分块)
- HDU 5213 Lucky [莫队+容斥]
- [HDU 5213]Lucky:莫队+容斥原理
- HDU 5213 Lucky 容斥+莫队
- hdu 5213 Lucky (莫队+容斥)
- 如何设置共享文件夹
- 【爬虫之路】批量下载5sing上一位歌手的全部歌曲
- SSH笔记-注解开发(2)各层次类的编写
- Linux内核ARP的处理函数分析(arp_rcv, arp_send)
- ASIC设计中一种通用型并行设计方法
- 【HDU】5213 Lucky 【分块(在线算法)】
- OpenGL配置过程
- 帮助命令
- Dom4j 学习笔记
- 如何进行 iOS 稳定性测试
- ORACLE中用rownum分页并排序的SQL语句
- VIM终极使用技巧
- 如何能够有效禁止u盘自动运行
- Android Instrumentation 判断跳转后的Activity