在普通的莫隊中引入一維時間戳,讀入時對每次詢問記錄最近一次修改的時間。離線操作時增加一維時間的操作,如果當前時間在當前詢問的時間戳之前,那麼把中間這一段時間的貢獻加入答案,否則,把多出來的這段時間的貢獻刪除。刪除的操作如下:正向經過時間是把修改貢獻乙個個累加,反向經過時間相當於把之前累加的貢獻還原,所以每正向經過時間就把當前的修改貢獻和本來的貢獻互換一下,當正向經過時間的時候把修改的貢獻加入把本來的貢獻刪除,互換過後當反向經過時間的時候就會把本來的貢獻加入而把修改的貢獻刪除,然後每反向經過時間也把修改的貢獻和本來的貢獻互換一下,下次正向經過時間又能達到同樣的效果。
時間複雜度上需要注意的地方:
1.排序方式(增加了一維時間戳後的排序方式):
bool friend operator板題 luogu p1903 [國家集訓隊]數顏色 / 維護佇列:2.分塊大小:
經過某些dalao證明分塊採用n^(2/3)的時間優於sqrt(n)的複雜度,因此可以這樣:
int siz = ceil(pow(n, 0.6666
));
for (register int i = 1; i <= n; i++) a[i] = rd(), pos[i] = i / siz;
#pragma gcc optimize(2)#includeview code#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define fi first
#define se second
#define re register
#define ls i << 1
#define rs i << 1 | 1
#define pb push_back
#define mp make_pair
#define pii pair#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define mod 1000000007
//#define int long long
using
namespace
std;
const
double eps = 1e-8
;const
int inf = 0x3f3f3f3f
;const
long
long inf = 0x3f3f3f3f3f3f3f3f
;const
double pi = acos(-1.0
);inline
intrd()
void
out(int
a)
if (a >= 10) out(a / 10
); putchar(a % 10 + '0'
);}intn, m;
const
int maxn = 233333
;const
int n = 1e6+10
;char
opt;
intres;
inta[maxn], pos[maxn], ans[maxn];
intcnt[n];
struct
q}q[maxn];
struct
cc[maxn];
intcntq, cntc;
//signed main()
else
}sort(q+1, q+cntq+1
);
int l = 1, r = 0, time = 0
;
for (register int i = 1; i <= cntq; i++)
swap(a[c[time].pos], c[time].color);
}while (time >qt)
swap(a[c[time].pos], c[time].color);
--time;
}ans[q[i].k] =res;
}for (register int i = 1; i <= cntq; i++)
return0;
}
參考部落格:
F Machine Learning(帶修莫隊)
f.machine learning 思路 統計每個數字出現的次數numi,記錄次數numi出現的次數cnti。然後就是帶修莫隊的事情了。注意 不要用node x,y,z 這種方式,不然就是錯,很迷。include include include include include includeusi...
數顏色(莫隊帶修)
數顏色題目鏈結 帶修改的莫隊,關於時間複雜度的分析沒仔細看,但是這是乙個能實現更改的離線操作,感覺在之前的維度上加了一維 時間維度,可以將狀態向前或者向後改變,而時間的變遷也用while來更新,以達到操作目的,sort規則也變成這樣 return qu a.l qu b.l qu a.r qu b....
帶修莫隊 數顏色
bzoj2120 帶修莫隊的做法 把所有修改也離線下來 新建乙個tk指標表示進行了k次修改,然後對於每個詢問記錄一下它之前有多少次修改,記為k,處理這個詢問時如果當前修改次數小於k,那麼就把tk往上滾,並進行修改,如果大於k,就把tk往下滾,並回溯修改 code include using name...