码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 551E - GukiZ and GukiZiana(分块)

时间:2015-06-15 23:27:53      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:

Problem E. GukiZ and GukiZiana

Solution:

  先分成N=sqrt(n)块,然后对这N块进行排序。

     利用二分查找确定最前面和最后面的位置。

  

技术分享
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
vector<int> s[1000];
ll add[1000], a[512346], pos[512346];
ll n, q, bk, N;

bool cmp( int x, int y )
{
    if( a[x] == a[y]  ) return x < y;
    return a[x] < a[y];
}

inline void modify( ll l, ll r, ll x )
{
    int k = pos[l], t = pos[r];

    if( k == t ) {
        for( ll i = l; i <= r; ++i )
            a[i] += x;
        sort( s[k].begin(), s[k].end(), cmp );
        return ;
    }

    for( ll i = k + ( pos[l - 1] == k ); i <= t - ( pos[r + 1] == t ) ; ++i )
        add[i] += x;

    if( pos[l - 1] == k ) {
        for( ll i = l; pos[i] == k; ++i ) {
            a[i] += x;
        }
        sort( s[k].begin(), s[k].end(), cmp );
    }

    if( pos[r + 1] == t ) {
        for( ll i = r; pos[i] == t; --i ) {
            a[i] += x;
        }
        sort( s[t].begin(), s[t].end(), cmp );
    }
}

inline ll query( ll x )
{
    int l = -1, r = -1, i;
    for( i = 1; i <= N; ++i ) {
        a[0] = x - add[i];
        auto it = lower_bound( s[i].begin(), s[i].end(), 0, cmp );
        if( it == s[i].end() ) continue;
        if( a[*it] + add[i] == x ) {
            l = *it;
            break;
        }
    }

    if( l == -1 ) return l;
    for( int  j = N; j >= i; --j ) {
        a[n + 1] = x - add[j];
        auto it = lower_bound( s[j].begin(), s[j].end(), n + 1, cmp );
        if( it == s[j].begin() ) continue;
        it--;
        if( a[*it] + add[j] == x ) {
            r = *it;
            break;
        }
    }
    return r - l;
}

int main()
{
    ios::sync_with_stdio( 0 );
    cin >> n >> q;
    bk = ceil( sqrt( 1.*n ) + 0.005 );
    for( int i = 1; i <= n; ++i ) {
        cin >> a[i];
        pos[i] = ( i - 1 ) / bk + 1;
        s[pos[i]].push_back( i );
    }
    N = ( n - 1 ) / bk + 1;
    for( int i = 1; i <= N; ++i ) {
        sort( s[i].begin(), s[i].end(), cmp );
    }
    ll cmd, l, r, x;
    for( int i = 1; i <= q; ++i ) {
        cin >> cmd;
        if( cmd == 1 ) {
            cin >> l >> r >> x;
            modify( l, r, x );
        } else {
            cin >> x;
            cout << query( x ) << "\n";
        }
    }
}
View Code

 

Codeforces 551E - GukiZ and GukiZiana(分块)

标签:

原文地址:http://www.cnblogs.com/keam37/p/4579352.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!