(題目鏈結)
看到題目就聯想到了【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 向別的區間轉移狀態時。有時是刪除。有時是插入。同時需要維護。這類問題需要插入和刪除,以及維護比較快的情況下。才可以實現。回滾莫隊 插入和刪除是互反的操作。對於有些問題。插入和刪除好辦。維護困難。回滾莫隊可以解決 插入維護時困難,或者,刪除維護時困難的問...