Hackerrank Week of Code 30 Range Modular Queries

来源:互联网 发布:google play推荐算法 编辑:程序博客网 时间:2024/05/16 06:43

题目大意

给定一个长度为n的序列,有q个询问,每个询问要求[l,r]之间有多少个ai % x=y

Data Constraint
n,q,ai4×104

题解

当询问的x小于等于n的时候,显然可以分块预处理。
x大于n的时候,x的倍数小于n个,所以可以莫队,记录一个桶。

时间复杂度:O(nn)

SRC

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std ;#define N 40000 + 10#define M 200 + 10struct Query {    int l , r , x , y ;    int h ;} Q[N] ;int Num[M][M][M] , T[N] ;int a[N] , Belong[N] , Ans[N] ;int n , m , Cnt , Block , Maxv ;bool cmp( Query a , Query b ) { return Belong[a.l] < Belong[b.l] || ( Belong[a.l] == Belong[b.l] && a.r < b.r ) ; }void Modify( int l , int r , int del ) {    for (int i = l ; i <= r ; i ++ ) T[a[i]] += del ;}int main() {    scanf( "%d%d" , &n , &m ) ;    Block = 200 ;    for (int i = 1 ; i <= n ; i ++ ) {        scanf( "%d" , &a[i] ) ;        Maxv = max( Maxv , a[i] ) ;        Belong[i] = i / Block + ( i % Block != 0 ) ;    }    for (int i = 1 ; i <= Block ; i ++ ) {        int now = 1 ;        for (int j = 1 ; j <= n ; j ++ ) {            if ( Belong[j] != now ) {                now ++ ;                for (int k = 0 ; k < i ; k ++ ) Num[i][now][k] = Num[i][now-1][k] ;            }            Num[i][now][a[j]%i] ++ ;        }    }    for (int i = 1 ; i <= m ; i ++ ) {        int l , r , x , y ;        scanf( "%d%d%d%d" , &l , &r , &x , &y ) ;        l ++ , r ++ ;        if ( x <= Block ) {            int fl = Belong[l] ;            int fr = Belong[r] ;            if ( fl < fr ) Ans[i] = Num[x][fr-1][y] - Num[x][fl][y] ;            if ( fl != fr ) {                for (int j = l ; j <= min( fl * Block , n ) ; j ++ )                    if ( a[j] % x == y ) Ans[i] ++ ;                for (int j = (fr - 1) * Block + 1 ; j <= r ; j ++ )                    if ( a[j] % x == y ) Ans[i] ++ ;            } else {                for (int j = l ; j <= r ; j ++ )                    if ( a[j] % x == y ) Ans[i] ++ ;            }        } else {            ++ Cnt ;            Q[Cnt].l = l , Q[Cnt].r = r , Q[Cnt].x = x , Q[Cnt].y = y ;            Q[Cnt].h = i ;        }    }    sort( Q + 1 , Q + Cnt + 1 , cmp ) ;    int lasl = 1 , lasr = 0 ;    for (int i = 1 ; i <= Cnt ; i ++ ) {        if ( lasl < Q[i].l ) Modify( lasl , Q[i].l - 1 , -1 ) ;        if ( lasr > Q[i].r ) Modify( Q[i].r + 1 , lasr , -1 ) ;        if ( lasl > Q[i].l ) Modify( Q[i].l , lasl - 1 , 1 ) ;        if ( lasr < Q[i].r ) Modify( lasr + 1 , Q[i].r , 1 ) ;        for (int k = Q[i].y ; k <= Maxv ; k += Q[i].x )            Ans[Q[i].h] += T[k] ;        lasl = Q[i].l , lasr = Q[i].r ;    }    for (int i = 1 ; i <= m ; i ++ ) printf( "%d\n" , Ans[i] ) ;    return 0 ;}

以上.

1 0
原创粉丝点击