HNOI2016模擬4 10 K小數查詢

2021-07-11 08:08:16 字數 1383 閱讀 1711

維護乙個長度為n的序列,使得其支援m次操作,包括區間插入和區間求k小數。

n,m<=80000,在任何時候|ai|<=5000000

一看到區間第k大/小,就想到了主席樹。

但這個是區間修改!

怎麼做呢?

(分塊**好)

觀察到時限7s,果斷上分塊。(複雜度好不科學)

分塊**好?!

用每乙個塊維護排過序後的塊和原來的塊,然後對於每次詢問,

二分答案?!

不科學的複雜度。

負數二分怎麼打?

平移就好嘍……

#include

#include

#include

#define fo(i,a,b) for(int i=a;i<=b;i++)

#define n 80005

#define m 400

#define inf 5000000

using namespace std;

struct notea[n],b[n];

bool cmp(note x,note y)

int n,m,q,bz,le,ri,k,u,v,lazy[m],l[m],r[m];

int find(int v,int

x) return le-l[v];

}bool check(int

x,int le,int ri)

if (u==v)

fo(i,le,r[u]) if (a[i].v+lazy[u]<=x) ans++;

fo(i,l[v],ri) if (a[i].v+lazy[v]<=x) ans++;

fo(i,u+1,v-1) ans+=find(i,x);

if (ans>=k) return

1;else

return0;}

int main()

fo(i,1,n) a[b[i].w].w=i;

for(scanf("%d",&q);q;q--)

if (u==v)

fo(i,le,r[u]) a[i].v+=k,b[a[i].w].v+=k;

sort(b+l[u],b+r[u]+1,cmp);

fo(i,l[u],r[u]) a[b[i].w].w=i;

fo(i,l[v],ri) a[i].v+=k,b[a[i].w].v+=k;

sort(b+l[v],b+r[v]+1,cmp);

fo(i,l[v],r[v]) a[b[i].w].w=i;

fo(i,u+1,v-1) lazy[i]+=k;

} else

printf("%d\n",u-inf);}}

}

HNOI2016模擬4 10 K小數查詢

維護乙個長度為n的序列,該序列支援q個操作 將第l到r個數加上x 詢問l到r之間第k小個數是什麼。看到實現時間7000ms,嘿嘿,果斷分塊打法。大呼 分塊 好 這題因為有區間加操作,直接用資料結構難以維護區間 k 小值。但是可以用 分塊解決此題。最簡單的方法是每個塊維護原塊和排序後的塊,詢問時二分答...

HNOI2016模擬4 10 線性代數與邏輯

這題廢了。首先,題意一定要明白。我們要構造乙個y陣列 一維,題目的 然後再構造出我們要的x矩陣。滿足xi,j yi yj 由於題目要 也就是對於每乙個位置 i,j 要使x i,j a i,j 然後,我們要讓 也就是說,y中0的個數和1的個數差最小。答案就是 上標 include include de...

HNOI2016模擬4 10 線性代數與邏輯

這題廢了。首先,題意一定要明白。我們要構造乙個y陣列 一維,題目的 然後再構造出我們要的x矩陣。滿足xi,j yi yj 由於題目要 也就是對於每乙個位置 i,j 要使x i,j a i,j 然後,我們要讓 也就是說,y中0的個數和1的個數差最小。答案就是 上標 include include de...