UESTC 数据结构专题 帆宝RMQ 分块+vector+结构体排序二分

这里写图片描述

思路:这题可以说是写的吐血了,只因为没有考虑到没有1操作,直接2操作询问的情况,分块之后就要rubuild ,不然直接二分查找vector内数据不是有序的就会混乱!!
Code:

#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int AX = 1e5+66;
int b[AX];
int n , q ;
LL add[AX];
int len ;
struct Node{
    int x , id; 
}a[AX];
std::vector<Node> s[AX];
bool cmp(const Node &a,const Node &b){ 
    if( a.x == b.x ) return a.id < b.id; 
    return a.x < b.x;  
} 

void rebuild( int t ){
    s[t].clear();
    for( int i = ( t - 1 ) * len + 1 ; i <= min( n , t * len ) ; i++ ){
        s[t].push_back(a[i]);
    }
    sort( s[t].begin() , s[t].end() , cmp );
}

void update( int l , int r , int c ){
    for( int i = l ; i <= min( r , b[l] * len ) ; i++ ){
        a[i].x += c;
    }
    rebuild( b[l] );
    if( b[l] != b[r] ){
        for( int i = ( b[r] - 1 ) * len + 1 ; i <= r ; i++ ){
            a[i].x += c;
        }
        rebuild( b[r] );
    }
    for( int i = b[l] + 1 ; i < b[r] ; i++ ){
        add[i] += c;
    }
}

int query( int v ){
    int li = INF;
    int ri = -INF;
    for( int i = 1 ; i <= b[n] ; i++ ){
        Node tmp ;
        tmp.x = v - add[i];
        tmp.id = 0;
        vector<Node>::iterator it = lower_bound( s[i].begin() , s[i].end() , tmp , cmp );
        if( it == s[i].end() ) continue;
        while( it != s[i].end() ){
            if( (*it).x == tmp.x ){
                li = min( li , (*it).id );
                ri = max( ri , (*it).id ); 
            }else break;
            it++;
        }
    }
    if( li == INF || ri == -INF )
        return -1;
    return ri - li;
}



int main(){
    scanf("%d%d",&n,&q);
    for( int i = 1 ; i <= n ; i++ ){
        scanf("%d",&a[i].x);
        a[i].id = i;
    }
    len = sqrt(n);
    for( int i = 1 ; i <= n ; i++ ){
        b[i] = (( i - 1 ) / len) + 1 ;
        s[b[i]].push_back( a[i] );
    }
    for( int i = 1 ; i <= b[n] ; i++ ){
        rebuild( i );
    }
    int op,l,r,x;
    while( q -- ){
        scanf("%d",&op);
        if( op == 1 ){
            scanf("%d%d%d",&l,&r,&x);
            update( l , r , x );
        }else{
            scanf("%d",&x);
            int res = query(x);
            printf("%d\n",res);
        }
    }
    return 0 ;
}



猜你喜欢

转载自blog.csdn.net/frankax/article/details/80425586