• Codeforces 551E


    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 ) << "
    ";
            }
        }
    }
    View Code
  • 相关阅读:
    丁丁又病了
    领导之所以是领导
    丁丁的进步
    最近比较烦
    批量更新数据表
    转帖:《EnterLib PIAB深入剖析》系列博文汇总
    XML DOM介绍
    转大白话系列之C#委托与事件讲解大结局
    using
    jQuery工作原理解析以及源代码示例
  • 原文地址:https://www.cnblogs.com/keam37/p/4579352.html
Copyright © 2020-2023  润新知