Time Limit:3s Memory Limit:256MBytehtml
Submissions:315Solved:71ios
壞壞い月是月大叔的ID,他是一個掌握者772002種魔法的物理系戰士,最擅長的技能就是搞事。今天他又要開始搞事了。數據結構
給你natom
個數,你須要實現一下操做:spa
l r v ,在[l,r]區間內找到第一個大於等於v的數,輸出這個數的下標,若是找不到的話,請輸出-1噢code
l r v,讓[l,r]區間全部數增長vxml
,表示有t組數據 對於每組數據: 第一行包含兩個整數n(1≤n≤100000),q(1≤q≤100000),表示數的個數,以及詢問的個數。 第二行包含n個整數 ai(1≤ai≤1000000000) 接下來q行,每行四個整數opt(1≤opt≤2),l,r(1≤l≤r≤n),v(1≤v≤1000000000)htm
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long LL; const int N = 100000; int n,m; LL a[N],Max[N],Upd[N]; int pos[N]; int block = 0; void reset(int x) { int l=(x-1)*block+1,r=min(x*block,n); for(int i=l; i<=r; i++) Max[x]=max(Max[x],a[i]); } void update(int x,int y,LL v) { if(pos[x]==pos[y]) { for(int i=x; i<=y; i++)a[i]=a[i]+v; } else { for(int i=x; i<=pos[x]*block; i++)a[i]=a[i]+v; for(int i=(pos[y]-1)*block+1; i<=y; i++)a[i]=a[i]+v; } reset(pos[x]); reset(pos[y]); for(int i=pos[x]+1; i<pos[y]; i++) Upd[i]+=v; } int findidx(int x,LL v) { int l=(x-1)*block+1,r=min(x*block,n); for(int i=l; i<=r; i++) { if(a[i]+Upd[x]>=v) return i; } } int query(int x,int y,LL v) { if(pos[x]==pos[y]) { for(int i=x; i<=y; i++)if(a[i]+Upd[pos[i]]>=v) return i; } else { ///暴力找左邊 for(int i=x; i<=pos[x]*block; i++) if(a[i]+Upd[pos[i]]>=v) return i; ///分塊找中間 for(int i=pos[x]+1; i<pos[y]; i++) if(Max[i]+Upd[i]>=v) { return findidx(i,v); } ///暴力找右邊 for(int i=(pos[y]-1)*block+1; i<=y; i++) if(a[i]+Upd[pos[i]]>=v) return i; } return -1; } int main() { int T; scanf("%d",&T); while(T--) { memset(Max,0,sizeof(Max)); memset(Upd,0,sizeof(Upd)); scanf("%d%d",&n,&m); block = int(sqrt(n)); for(int i=1; i<=n; i++) { scanf("%lld",&a[i]); pos[i]=(i-1)/block+1; ///記錄每一個元素屬於哪一個塊 } int k; ///塊的個數 if(n%block)k=n/block+1; else k=n/block; for(int i=1; i<=k; i++) { reset(i); } while(m--) { int opt,l,r; LL v; scanf("%d%d%d%lld",&opt,&l,&r,&v); if(opt==1) { printf("%d\n",query(l,r,v)); } else { update(l,r,v); } } } return 0; }