[JZOJ4438] K小數查詢(經典分塊)
Description
給你
1 L R x 將L 到R 加上x 2 L R k 求L 到R 第k 小的數
Solution
分塊大法好!
我們將序列分成
修改整塊的就直接打標記,兩邊的暴力重構該塊
關鍵在查詢!
我們可以二分一個答案(思考一下,二分出來的答案會不會序列中不存在呢?)
然後轉化成判定性問題,判斷二分出來的答案是不是在第
只需要對於每個塊,找該塊中小於這個值的個數,全部加起來看是不是
證明一下這樣為什麼不會出現不存在的答案
假設正確答案是
小於等於
所以二分出來的一定是
Code
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
#define mo 1000000007
using namespace std;
int pl[500],wz[80605],n,m,size;
struct note
{
int x,y;
}a[80605],b[80605];
bool cmp(note x,note y)
{
return x.x<y.x;
}
int nt(int k)
{
return ((k-1)/size+1)*size+1;
}
int pd(int l,int r,int k)
{
int p=nt(l),sum=0,i;
note k1;
k1.x=k;
while (nt(p)<r+1)
{
k1.x-=pl[wz[p]];
sum+=lower_bound(b+p,b+nt(p),k1,cmp)-b-p;
k1.x+=pl[wz[p]];
p=nt(p);
}
if (nt(l)>r)
{
fo(i,l,r) if (a[i].x<k-pl[wz[i]]) sum++;
}
else
{
fo(i,l,nt(l)-1) if (a[i].x<k-pl[wz[i]]) sum++;
fo(i,p,r) if (a[i].x<k-pl[wz[i]]) sum++;
}
return sum;
}
int main()
{
int i,j;
cin>>n;
size=(int)sqrt(n);
fo(i,1,n)
{
scanf("%d",&a[i].x);
b[i].x=a[i].x;
b[i].y=i;
}
j=1;
wz[j]=1;
while (j+size<=n+1)
{
sort(b+j,b+j+size,cmp);
j+=size;
wz[j]=wz[j-size]+1;
}
if(j!=n+1) sort(b+j,b+n+1,cmp);
fo(i,1,n)
{
if (wz[i]==0) wz[i]=wz[i-1];
a[b[i].y].y=i;
}
cin>>m;
int i1=0;
fo(i,1,m)
{
int p,l,r,k,j;
scanf("%d%d%d%d",&p,&l,&r,&k);
if (p==1)
{
j=nt(l);
while (nt(j)<=r)
{
pl[wz[j]]+=k;
j=nt(j);
}
int q;
if (nt(l)>r)
{
fo(q,l,r) a[q].x=b[a[q].y].x=a[q].x+k;
sort(b+nt(l)-size,b+nt(l),cmp);
fo(q,nt(l)-size,nt(l)-1) a[b[q].y].y=q;
}
else
{
fo(q,l,nt(l)-1) a[q].x=b[a[q].y].x=a[q].x+k;
sort(b+nt(l)-size,b+nt(l),cmp);
fo(q,nt(l)-size,nt(l)-1) a[b[q].y].y=q;
fo(q,j,r) a[q].x=b[a[q].y].x=a[q].x+k;
sort(b+j,b+nt(j),cmp);
fo(q,j,nt(j)-1) a[b[q].y].y=q;
}
}
else
{
int x=-5000000,y=5000000,mid;
while (x<y-1)
{
mid=(x+y)/2;
if (pd(l,r,mid)<=k-1) x=mid;
else y=mid;
}
if (pd(l,r,y)==k-1) printf("%d\n",y);
else printf("%d\n",x);
}
}
}
相關推薦
[JZOJ4438] K小數查詢(經典分塊)
Description 給你N個數組成的序列,需要支援兩種操作 1 L R x 將L到R加上x 2 L R k 求L到R第k小的數 Solution 分塊大法好! 我們將序列分成N−−√塊,每塊中維護原來的順序的值,以及將該塊所有值
bzoj5037 線段樹練習4加強版(暴力分塊)
log del string 技術分享 iostream || getc code click 求大爺教線段樹怎麽寫啊QAQ 只會寫分塊...一開始腦抽寫成了O(NKlogN)還被CZL大爺嘲諷了一發T T f[i][j]表示在第i塊中,模k為j的數有幾個,
【bzoj4765】普通計算姬(雙重分塊)
efi ref space include pos gif signed problem 。。 題目傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=4765 這道題已經攢了半年多了。。。因為懶,一直沒去寫。。
bzoj3436: 小K的農場(差分約束)
col bsp pac als OS namespace mat else center 3436: 小K的農場 題目:傳送門 題解: 查分基礎: t==1 a>=b+c t==2 b>=a-c t==3 a>=b+
51Nod 1225 - 餘數之和(整除分塊)
【題目描述】 【思路】 整除分塊+等差數列 設 p = ⌊
【洛谷3396】雜湊衝突(大力分塊)
點此看題面 大致題意:給你一個長度為nn的陣列valval以及mm個操作,操作有兩種:一種是將valxvalx修改為yy,另一種操作是求出∑vali(i∑vali(i%x=y)x=y)。 樸素的暴力 我們先
牛客網練習賽25A—因數個數和(整除分塊)
題目描述 q次詢問,每次給一個x,問1到x的因數個數的和。 輸入描述: 第一行一個正整數q ; 接下來q行,每行一個正整數 x 輸出描述: 共q行,每行一個正整數表示答案 題意: 給你一個n,求1的因子數+2的因子數+3的因子數+......+n的因子數。
jzoj5936 【NOIP2018模擬10.29】逛公園 (性質+分塊)
Description 策策同學特別喜歡逛公園,公園可以看做有n個景點的序列,每個景點會給策策帶來di 的愉悅度,策策初始有x0 的愉悅度,然而愉悅度也是有上限的,他在每個景點的愉悅度上限為li ,策策想要從 l 到 r這一段景點中選擇一段景點參觀(從這一段的左
【洛谷5113】Sabbat of the witch(毒瘤分塊)
點此看題面 大致題意: 給你一個序列,要你支援三種操作:區間賦值,區間求和,撤回之前任一區間賦值操作。 分塊 這道題應該是一道十分毒瘤的分塊題。 這道題要用到的演算法並不是很難,但是思維難度是真的高。 大致思路就是對於每一個塊維護一大堆資訊,各用一個棧儲存對每個塊的賦值操作,並開一個鄰接表來儲存
查詢區間內等於x的數的個數(分塊)
問題:有一個有n個數的陣列,q次查詢,每次查詢l, r ,x,查詢區間[l,r]內等於x的數的個數思路:分塊。就把這題當成是分塊的入門題來講解一下分塊。分塊其實就是一種比較優美的暴力(我覺得),一般的分塊都是把長度為n的陣列分成每一塊為sqrt(n)個數的多個塊。然後對於區間
【bzoj2724】蒲公英(分塊)
sort 大小 int gin algorithm read oid n) 快速合並 題目分析 付費題哈哈。題意就是求區間眾數,由於區間眾數無法快速合並,所以不能使用傳統的數據結構如線段樹等。 這時分塊就能派上很大的用場。將序列分成$\sqrt{n}+$塊,每塊大小$\
HDU 6053 TrickGCD(分塊)
%d space 復雜 cstring 前綴 == str 結果 logs 【題目鏈接】 http://acm.hdu.edu.cn/showproblem.php?pid=6053 【題目大意】 給出一個數列每個位置可以取到的最大值, 問這個
計蒜客16492 building(二分線段樹/分塊)
sin cst include sqrt ++ building scanf mat math 題解: 考慮用線段樹維護樓的最大值,然後這個問題就很簡單了。 每次可以向左二分出比x高的第一個樓a,同理也可以向右二分出另一個樓b,如果a,b都存在,答案就是b-a-1。 註意到
Topcoder SRM 675 Div1 500Pts LimitedMemorySeries1(分塊)
tor bits fin get pre n) ted 多少 top 題意 給定一個長度不超過$5*10^{6}$的數列和不超過$100$個詢問,每次詢問這個數列第$k$小的數,返回所有詢問的和 內存限制很小,小到不能存下這個數列。(數列以種子的形式給出)
bzoj3920: Yuuna的禮物(莫隊+分塊套分塊)
max ons del closed 感覺 做到 bzoj ace clu 思路挺簡單的,但是總感覺好難寫...碼力還是差勁,最後寫出來也挺醜的 這題顯然是個莫隊題,考慮怎麽轉移和詢問... 根據莫隊修改多查詢少的特點,一般用修改快查詢慢的分塊來維護。查第$
sql 分頁查詢 (每次6行 )
分享 數據 mage com http 行數 -- where SQ -- 對比 數據 是否 相同 select * from [dbo].[ProjecrInfo] where Project_state=‘已審核‘ -- 查詢 已經 審核 有多少數據 -- 每次 按
bzoj3994: [SDOI2015]約數個數和(莫比烏斯反演+分塊)
put name 一行 AI algorithm scan space 代碼 print www.cnblogs.com/shaokele/ bzoj3994: [SDOI2015]約數個數和 Time Limit: 20 Sec Memory Limit: 1
BZOJ2821 作詩(分塊)
span -o 一模一樣 sin include pre getch pan ostream 和區間眾數幾乎一模一樣的套路。 // luogu-judger-enable-o2 #include<iostream> #include<cstdio>
【OJ2130】K小數查詢
很好 print char line 分塊 con 多少 第一個 () 2130 -- K小數查詢(Solution) 題目大意 : 給你一個長度為 \(N\) 的數列和 \(Q\) 個操作,操作包括:①區間加一個數;②詢問區間內第 \(k\) 小的數。\((n,q\le8
BZOJ 3110 [Zjoi2013]K大數查詢(整體二分)
題解 gre void 有關 pre \n str k大數查詢 如果 3110: [Zjoi2013]K大數查詢 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 11654 Solved: 3505[Submit][Sta