問題:有乙個有n個數的陣列,q次查詢,每次查詢l, r ,x,查詢區間[l,r]內等於x的數的個數
思路:分塊。
就把這題當成是分塊的入門題來講解一下分塊。分塊其實就是一種比較優美的暴力(我覺得),一般的分塊都是把長度為n的陣列分成每一塊為sqrt(n)個數的多個塊。然後對於區間的操作就可以不再是乙個乙個數進行處理,而是可以乙個塊乙個塊的處理,每次查詢最多會涉及到sqrt(n)個塊,這樣複雜度就降了下來。
(先進行幾點說明,本文中的陣列下標從1開始,塊的編號也是從1開始,每個塊的大小k = sqrt(n))
分塊過後的對於區間[l,r]的操作就分為兩種情況:
設cl為區間左端點l所在的塊號,cr為區間右端點r所在的塊號。那麼怎麼求乙個下標所屬的塊號呢,很簡單:(x-1)/k + 1。
第一種情況是cl == cr,也就是左右端點在同乙個塊內,這樣直接從l迴圈到r處理操作就可以了,複雜度很顯然最多是sqrt(n)
第二種情況我們可以統一的假定為 cl != cr,這樣我們可以把區間分為三部分,一是l到cl*k這部分可以直接迴圈操作,後面就是第cl+1塊到cr-1塊這部分,最後就是(cr-1)*k+1到r這部分。
這一題要求的是乙個區間內等於x的有多少個數,我們可以對每乙個塊進行排序,然後就可以用二分求出等於x的個數。
#include#include#include#include#includeusing namespace std;
const int maxn = 300010;
int a[maxn];
int b[maxn];
int n,k;
int li(int x) //求x的塊號
int query(int l,int r,int x)
for(i=l;i<=cl*k;i++)
for(i=cl+1;in)
break;
sort(b+(i-1)*k+1,b+min(i*k,n)+1);
}int q;
scanf("%d",&q);
while(q--)
return 0;
}
查詢任意區間內不同元素的個數
include using namespace std define ll long long const int maxn 2e5 5 const int mod 1e9 7 const double eps 1e 9 const double pi acos 1.0 const int inf ...
判斷區間內的素數個數
package method public class stest package method 編寫乙個有兩個執行緒的程式,第乙個執行緒用來計算2 100000之間的素數的個數,第二個執行緒用來計算100000 200000之間的素數的個數,最後輸出結果 author administrator ...
非負整數區間內含某數字的數的個數
群裡有人問了這個問題 然後被attack秒了orz 考慮數字dp 預處理v 第幾位 該位是否是目標數字 是否有目標數字 顯然數字除了0之外的求解過程是完全一致的 那麼我們特判0就可以了 include cstdio include cstring include iostream include a...