維護乙個長度為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...