單點插入,單點詢問。html
分塊的小技巧可多啦 O(∩_∩)O哈哈~c++
用一個vector來記錄每一個塊的元素。vector提供了強大的insert函數,插入某個元素只要寫一點點就能夠啦O(∩_∩)O,就是一個一個枚舉塊,直到找到插入位置屬於哪一個塊,而後insert一下就OK。不過,若是插入元素集中於一個塊的話就尷尬了QAQ複雜度飆升。因此咱們要對塊進行從新分配。我採用若一個塊元素多於10倍原有元素個數時就重排~(因爲數據隨機分配,不進行重排其實也不會TLE,甚至直接1個vector插入也能過 QAQ 數據水???建議仍是寫下重排,由於徹底能夠卡掉不重排的)數組
#include<bits/stdc++.h> using namespace std; #define MAXN 100005 int n, d, nn; int a[MAXN<<1]; vector<int> v[1005]; inline void mer(){//把全部元素還原到a數組中 n = 0; for ( int i = 1; i <= d + 1; ++i ){ if ( v[i].empty() ) break; for ( int j = 0; j < v[i].size(); ++j ) a[++n] = v[i][j]; v[i].clear(); } } inline void div(){//把a數組元素分配到各個塊中 d = sqrt(n); for ( int i = 1; i <= n; ++i ) v[( i - 1 ) / d + 1].push_back(a[i]); } inline int Get( int wh ){ for ( int i = 1; i <= d + 1; ++i ){ if ( wh > v[i].size() ) wh -= v[i].size(); else return v[i][wh - 1]; } } inline void Ins( int wh, int x ){ for ( int i = 1; i <= d + 1; ++i ){ if ( wh > v[i].size() ) wh -= v[i].size(); else{ v[i].insert( v[i].begin() + wh - 1, x );//插入~ if ( v[i].size() > 10 * d ) mer(), div();//重排 return; } } } int main(){ scanf( "%d", &n ); for ( int i = 1; i <= n; ++i ) scanf( "%d", &a[i] ); div(); nn = n; for ( int i = 1; i <= nn; ++i ){ int opt, l, r, c; scanf( "%d%d%d%d", &opt, &l, &r, &c ); if ( opt ) printf( "%d\n", Get(r) ); else Ins( l, r ); } return 0; }
有些分塊的技巧性很強,平時注意概括(*^▽^*)
函數
數列分塊入門1spa
數列分塊入門2code
數列分塊入門3htm
數列分塊入門4blog
數列分塊入門5get
數列分塊入門6 <-it