$n \leq 10000$的數列,$m \leq 10000$個操作,一:單點修改;二:查區間不同數字個數。修改數$\leq 1000$,數字$\leq 1000000$。
我不會告訴您這是三種寫法的雙倍經驗題!!
一般可以把查區間不同個數改成:$pre_i$表示$i$之前的乙個與她相同的數在哪,然後變成查某個區間$pre_i$在某個範圍內的數量。可以主席樹,也可分塊。修改暴力重構。
方法三:帶修莫隊。按l塊為第一關鍵字、r塊為第二關鍵字、時間為第三關鍵字對詢問排序,這樣時間指標的移動複雜度是塊數量的平方乘修改數。
理論上塊大小取$n^}$是最好的,但是注意一下修改數只有1000。。於是求個導畫個圖象(用電腦)可得塊大小280左右時最優。加了個離散化跑得飛起。
1view code//#include
2 #include3 #include4 #include5
//#include6//
#include7//
#include
8 #include9 #include10
using
namespace
std;
1112
intn,m,lq,lc,tot;
13#define maxn 10011
14#define maxm 288
15int
a[maxn],bel[maxn];
16struct quesq[maxn];
17bool cmp(const ques a,const ques b)
18struct modimo[maxn];
1920
int lisa[maxn<<1
],li;
21int ss; int cnt[maxn<<1
],ans[maxn];
22void modify(int p,int type)
23void timemodify(int l,int r,int p,int v)
2425
intmain()
2639
else
4044
}45 lq-=lc;
46 sort(lisa+1,lisa+1+li); li=unique(lisa+1,lisa+1+li)-lisa-1;47
for (int i=1;i<=n;i++) a[i]=lower_bound(lisa+1,lisa+1+li,a[i])-lisa;
48for (int i=1;i<=lc;i++) mo[i].a=lower_bound(lisa+1,lisa+1+li,mo[i].a)-lisa,
49 mo[i].b=lower_bound(lisa+1,lisa+1+li,mo[i].b)-lisa;
5051 sort(q+1,q+1+lq,cmp);
52int l=1,r=0,t=lc; ss=0;53
for (int i=1;i<=lq;i++)
5463
for (int i=1;i<=lq;i++) printf("
%d\n
",ans[i]);
64return0;
65 }
BZOJ 2120 數顏色 莫隊
題目傳送門 觀察前兩題,莫隊演算法好像是一種只支援查詢的離線演算法,但是莫隊真的不支援修改嗎?答案當然是否定的 莫隊是一種支援查詢和修改的離線演算法。就是一種優美的暴力 考慮在莫隊演算法中增加乙個變數no w 表示當前有no w 個修改已經修改掉了。並在每乙個詢問中增加乙個變數pr e 表示最近的修...
BZOJ 2120 帶修改莫隊
簡略題意 單點修改,區間查詢不同顏色個數。帶修改莫隊的板題,學習了乙個。和普通莫隊的區別在於塊的大小需要設定為n2 3,這樣可以確保複雜度為o n3 5 每次詢問之前需要把在當前時間點之前的所有修改用上,這之後的所有修改刪掉。define others ifdef poj include inclu...
BZOJ 2120 數顏色(帶修莫隊)
給定乙個序列要求查詢乙個區間不同顏色的個數,支援修改操作。記乙個看起來很sb時間複雜度o n5 3 o n 5 3 連暴力都是o n2 o n 2 但是有些時候可以代替樹套樹而且空間非常小而且超好些的高科技演算法帶修莫隊 時間複雜度就懶得分析了。說幾個細節吧 include using namesp...