日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

「分块系列」数列分块入门3 解题报告

發布時間:2023/12/19 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 「分块系列」数列分块入门3 解题报告 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數列分塊入門3

題意概括

區間加法,區間求前驅。

寫在前面

這題的方法與分塊2方法極其類似,建議自行解決。

正題

和上一題類似,但是二分不是用來計數的,而是用來求小于c的最大值的。然后對于不完整快,將小于c的值求最大值,再與所有塊中二分結果求最大值即可。(其他思路上一篇題解已經講了,這里不再復述,代碼注釋也懶得打了,因為比較簡單,很容易理解)

代碼

#include<cstdio> #include<vector> #include<algorithm> #include<cmath> using namespace std; #define MAXN 100005int n, m, a[MAXN], p[MAXN], b[1005], mm; vector<int> v[1005]; int opt, l, r, c;int EF( vector<int> vec, int x ){int l, r, mid, ans(-1);l = 0; r = vec.size() - 1;while( l <= r ){mid = ( l + r ) >> 1;if ( vec[mid] < x ){ans = mid;l = mid + 1;}else r = mid - 1;}return ans; }int query( int l, int r, int c ){int ans(-1);if ( p[l] == p[r] ){for ( int i = l; i <= r; ++i )if ( a[i] + b[p[l]] < c ) ans = max( ans, a[i] + b[p[l]] );return ans;}for ( int i = l; p[i] == p[l]; ++i )if ( a[i] + b[p[i]] < c ) ans = max( ans, a[i] + b[p[l]] );for ( int i = r; p[i] == p[r]; --i )if ( a[i] + b[p[i]] < c ) ans = max( ans, a[i] + b[p[r]] );for ( int i = p[l] + 1; i <= p[r] - 1; ++i ){int t(EF( v[i], c - b[i] ));if ( t >= 0 ) ans = max( ans, v[i][t] + b[i] );}return ans; }void re( int x ){v[x].clear();int be(( x - 1 ) * m + 1);for ( int i = be; p[i] == p[be]; i++ ) v[x].push_back( a[i] );sort( v[x].begin(), v[x].end() ); }void Add( int l, int r, int c ){if ( p[l] == p[r] ){for ( int i = l; i <= r; ++i ) a[i] += c;re( p[l] ); return; }for ( int i = l; p[i] == p[l]; ++i ) a[i] += c;re(p[l]);for ( int i = r; p[i] == p[r]; --i ) a[i] += c;re(p[r]);for ( int i = p[l] + 1; i < p[r]; ++i ) b[i] += c; }int main(){scanf( "%d", &n ); m = (int)sqrt(n);for ( int i = 1; i <= n; ++i ) p[i] = ( i - 1 ) / m + 1, mm = p[i];for ( int i = 1; i <= n; ++i ) scanf( "%d", &a[i] );for ( int i = 1; i <= n; ++i ) v[p[i]].push_back(a[i]);for ( int i = 1; i <= mm; ++i ) sort( v[i].begin(), v[i].end() );for ( int i = 1; i <= n; ++i ){scanf( "%d%d%d%d", &opt, &l, &r, &c );if ( opt ) printf( "%d\n", query( l, r, c ) );else Add( l, r, c );}return 0; }

總結

分塊切記要觸類旁通,充分發揮分塊的靈活性。

數列分塊系列目錄

數列分塊入門1

數列分塊入門2

數列分塊入門3 <-

數列分塊入門4

數列分塊入門5

數列分塊入門6

數列分塊入門7

數列分塊入門8

數列分塊入門9

蒲公英

公主的朋友

轉載于:https://www.cnblogs.com/louhancheng/p/10051153.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的「分块系列」数列分块入门3 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。