【OJ2130】K小數查詢
阿新 • • 發佈:2018-08-04
很好 print char line 分塊 con 多少 第一個 () 系列查找函數即可。
2130 -- K小數查詢(Solution)
題目大意 : 給你一個長度為 \(N\) 的數列和 \(Q\) 個操作,操作包括:①區間加一個數;②詢問區間內第 \(k\) 小的數。\((n,q\le80000)\) .
Tag: 二分、分塊
Analysis By LC:
我知道這題可以用主席樹做,但像我這麽菜的鹹魚選手怎麽可能會主席樹。所以我們用分塊。
第一個操作時分塊常規操作,但第二個看起來不是很好做。我們可以嘗試用二分答案轉化問題求解,:一個數有至少 \(k-1\) 個數比它小,該數最小值即為所求。那麽我們只需對於每個塊,找出有多少個數比該數小就行了。我們可以維護每一塊排序後的數列,查詢時僅需用STL的 \(bound\)
雖然是分塊套路題,但個人認為細節還是不少,可能是我太菜了吧。
Code By LC :
#include<cstdio> #include<algorithm> using namespace std; inline int _read() { char c; int x=0,f=1; for(;c<'0'||c>'9';c=getchar())if(c=='-')f=-1; for(;c>='0'&&c<='9';c=getchar())x=(x<<1)+(x<<3)+c-'0'; return x*f; } const int N=80005,INF=5000000; int n,a[N],ind,l[N],r[N],id[N],ta[N],isl[N],pos[N]; struct node { int id,w; bool operator < (const node x) const { return w < x.w; } } s[N]; void rebuild(int x) { sort(s+l[x],s+1+r[x]); for(int i=l[x];i<=r[x];i++) pos[s[i].id]=i; } bool check(int mid, int ql, int qr, int x) { int k=0,i; for(;ql<=qr&&!isl[ql];ql++)k+=(s[pos[ql]].w+ta[id[ql]]<=mid); if(ql>n||ql>qr) return k>=x; for(i=isl[ql];i<=ind&&r[i]<=qr;i++) { int tmp=upper_bound(s+l[i],s+1+r[i],(node){-1,mid-ta[i]})-s; k+=tmp-l[i]; } if(i>ind) return k>=x; for(ql=l[i];ql<=qr;ql++)k+=(s[pos[ql]].w+ta[id[ql]]<=mid); return k>=x; } int main() { n=_read(); const int m=sqrt(n); for(int i=1;i<=n;i=min(n,i+m-1)+1) { l[++ind]=i,r[ind]=min(n,i+m-1); isl[i]=ind; } for(int i=1;i<=ind;i++) for(int j=l[i];j<=r[i];j++) id[j]=i; for(int i=1;i<=n;i++) s[i]=(node){i,_read()}; for(int i=1,k=0;i<=ind;i++) sort(s+l[i],s+1+r[i]); for(int i=1;i<=n;i++) pos[s[i].id]=i; int q=_read(); while(q--) { int op=_read(),ql=_read(),qr=_read(),x=_read(); if(op==1) { int i; for(;ql<=qr&&!isl[ql];ql++) s[pos[ql]].w+=x; rebuild(id[ql-1]); if(ql>qr) continue; for(i=isl[ql];i<=ind&&r[i]<=qr;i++)ta[i]+=x; if(i<=ind) for(ql=l[i];ql<=qr;ql++) s[pos[ql]].w+=x; rebuild(i); } if(op==2) { int tl=-INF,tr=INF; while(tl<=tr) { int mid=tl+tr>>1; if(check(mid,ql,qr,x)) tr=mid-1; else tl=mid+1; } printf("%d\n",tr+1); } } }
【OJ2130】K小數查詢