題目描述
給出乙個長為 nn 的數列,以及 nn 個操作,操作涉及區間加法,詢問區間內小於某個值 xx 的前驅(比其小的最大元素)。
輸入格式
第一行輸入乙個數字 nn。
第二行輸入 nn 個數字,第 ii 個數字為 a_iai,以空格隔開。
接下來輸入 nn 行詢問,每行輸入四個數字 \mathrmopt、ll、rr、cc,以空格隔開。
若 \mathrm = 0opt=0,表示將位於 [l, r][l,r] 的之間的數字都加 cc。
若 \mathrm = 1opt=1,表示詢問 [l, r][l,r] 中 cc 的前驅的值(不存在則輸出 -1−1)。
輸出格式
對於每次詢問,輸出一行乙個數字表示答案。
樣例樣例輸入
4
1 2 2 3
0 1 3 1
1 1 4 4
0 1 2 2
1 1 2 4
樣例輸出
3
-1
思路:第三題和第二題思路是樣的,因為是要找c的前驅,暴力找左右不完整塊的比c小最大值,再二分找完整塊比c小最大值,取其中最大即可。
ac**:
#include#include#include#include#include#include#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int s[maxn],flag[maxn],pos[maxn],ans,tag,n,m;
vectorv[1010];
void reset(int x)//用於對不完整塊排序
void update(int l,int r,int c)//更新值,第乙個操作
for(int i=pos[l]+1;i<=pos[r]-1;i++)//b陣列儲存完整塊的加值
flag[i]+=c;
}void query(int l,int r,int x)
}if(pos[l]!=pos[r])//暴力找右邊不完整塊 }}
for(int i=pos[l]+1;i<=pos[r]-1;i++)//整塊用二分查詢
}if(tag)
printf("%d\n",ans);
else
printf("-1\n");
}int main()
return 0;
}
(分塊)LOJ 6279 數列分塊入門 3
傳送門 loj 6279.數列分塊入門 3 題意 給出乙個長為n的數列,以及n個操作,操作涉及區間加法,詢問區間內小於某個值x的前驅 比其小的最大元素 以下引用hzwer大佬的解答 n 100000其實是為了區分暴力和一些常數較大的寫法。接著第二題的解法,其實只要把塊內查詢的二分稍作修改即可。不過這...
分塊4 6280 數列分塊入門 4
題目描述 給出乙個長為 nn 的數列,以及 nn 個操作,操作涉及區間加法,區間求和。輸入格式 第一行輸入乙個數字 nn。第二行輸入 nn 個數字,第 ii 個數字為 a iai 以空格隔開。接下來輸入 nn 行詢問,每行輸入四個數字 mathrmopt ll rr cc,以空格隔開。若 mathr...
數列分塊入門2
題目鏈結 給出乙個長為 n 的數列,以及 n 個操作,操作涉及區間加法,詢問區間內小於某個值 的元素個數。根據數列分塊入門1的思想,把n個數分為根號n塊,不完整塊的去暴力求和和查詢,完整塊用加法標進行標記,查詢排序後進行二分查詢。include include include include inc...