bzoj4241 歷史研究

2021-07-15 22:53:05 字數 1336 閱讀 5888

(題目鏈結)

看到題目就聯想到了【bzoj2809】 apio2012—dispatching。想了想權值分塊+莫隊,發現不好維護塊內最值,又看了看80s的時間,於是怒水一發線段樹+莫隊,結果先wa後tle,不斷tle,無論怎麼改常數都不行,難道nlogn*sqrt(n)就是過不了嗎!!不爽,蒯個題解,再見!

題意:求區間加權眾數。

solution

貌似是分塊,離散化之後,用mx[i][j]表示第i塊到第j塊的答案,cnt[i][j]表示前i塊數字j的個數。

**:

// bzoj4241

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 2147483640

#define pi acos(-1.0)

#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);

using namespace std;

inline ll getint()

while (ch>='0' && ch<='9')

return

x*f;

}const int maxn=100010;

struct data a[maxn];

int b[maxn],pos[maxn],l[400],r[400],cnt[400][maxn],num[maxn],st[maxn];

ll mx[400][400],ans;

int n,m,block,tot,top;

bool cmp(data a,data b)

while (top) num[st[top--]]=0;

return ans;

}

void build()

for (int i=1;i<=n;i++) cnt[pos[i]][b[i]]++;

for (int i=2;i<=tot;i++)

for (int j=1;j<=n;j++) cnt[i][j]+=cnt[i-1][j];

}int main()

build();

for (int i=1;i<=tot;i++)

}memset(num,0,sizeof(num));

for (int i=1;i<=m;i++)

printf("%lld\n",ans);}}

return

0;}

bzoj4241 歷史研究

這題也是坑了好久 之前whx帶我刷joi的時候本來應該要做的。可是太懶沒有寫。區間詢問加權眾數。分塊,預處理出塊和塊之間的答案,記錄到第i個塊數字x出現了多少次。然後查詢的時候和普通眾數基本一樣,就是乘了個權值而已。要離散化。時間複雜度o nlogn mn 昨晚寫的常數太爛了。用了struct,陣列...

BZOJ4241 歷史研究

一眼覺得是莫隊,發現刪除不是很好搞,於是上回滾莫隊直接搞過 回滾莫隊用於處理難以刪除但是易於新增 其實易於刪除難以新增也可以,但是沒見過這樣題 的莫隊,排序照常,如果左右端點在同一塊直接暴力,這部分最多n sqrt n,否則把左端點在一塊的一起處理,清空莫隊,然後直接令莫隊左端點在塊尾,這部分n s...

BZOJ 4241 歷史研究

藉此學習回滾莫隊。經典的莫隊 對於區間 l r 向別的區間轉移狀態時。有時是刪除。有時是插入。同時需要維護。這類問題需要插入和刪除,以及維護比較快的情況下。才可以實現。回滾莫隊 插入和刪除是互反的操作。對於有些問題。插入和刪除好辦。維護困難。回滾莫隊可以解決 插入維護時困難,或者,刪除維護時困難的問...