P5268 乙個簡單的詢問(莫隊 容斥)

2022-09-09 12:15:19 字數 1552 閱讀 6493

給你乙個長度為 n

n 的序列 aia

i,1≤i

≤n1≤

i≤n,和 q

q 組詢問,每組詢問讀入 l1,

r1,l

2,r2

l1,r

1,l2

,r2,需輸出∑x

=0∞get(l

1,r1

,x)×

get(l2

,r2,

x)x=

0∑∞get(l

1,r1

,x)×

get(l2

,r2,

x)get(l,

r,x)

get(l,

r,x)

表示計算區間 [l,

r][l

,r] 中,數字 x

x 出現了多少次。

\(n,m<=50000\)

\(1<=a[i]<=n\)

5

1 1 1 1 1

21 2 3 4

1 1 4 4

4

1

題目 \(r_1,l_2\) 的大小並不明確,需要另一種新穎的容斥方法

另 \([l,r]\) 為區間內 \(x\) 的個數,\(x\) 任意

之後 \([l1,r1]*[l2,r2]\) 可以轉化為

\[[1,r1]*[1,r2]-[1,r1]*[1,l2-1]-[1,r2]*[1,l1-1]+[1,l1-1]*[1,l2-1]

\]每乙個區間的左端點都為 \(1\),所以可以將乙個區間分為 \(4\) 個不同的區間,而他們的左端點都為 \(1\);

也就是說對於每乙個端點 \(l,r\) 對於 \(1\) 來說,都是右端點

\(hint:\) 區間大小是題目所給的 \(4\) 倍

const int n = 5e4 * 4 + 5;

int n, m;

int a[n];

struct query

query(int l = 0, int r = 0, int id = 0, int tag = 0, int bel = 0) : l(l), r(r), bel(bel), id(id), tag(tag){}

}q[n];

int block, pre[n], suf[n];

int tot = 0;

ll ans[n], now;

void add(int pos, int *on, int *nxt)

void del(int pos, int *on, int *nxt)

void mo()

sort(q + 1, q + 1 + tot);

}signed main()

mo();

int l = 0, r = 0;

now = 0;

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

rep(i, 1, m) pll(ans[i]);

}return 0;

}

洛谷P5268 乙個簡單的詢問

傳送門 to luogu 首先它是個莫隊的題。為什麼?我也不知道 但是莫隊只能處理兩個變數的詢問 並且任意乙個變數的移動對答案的影響可以快速計算,一般是 o 1 mathcal o 1 o 1 所以只好把這個式子變換一下。記 f m x j 1 m aj x f m,x sum a j x f m,...

洛谷P5286 乙個簡單的詢問

給你乙個長度為 n 的序列 a i 1 leq i leq n 和 q 組詢問,每組詢問讀入 l 1,r 1,l 2,r 2 需輸出 sum limits infty text l 1,r 1,x times text l 2,r 2,x text l,r,x 表示計算區間 l,r 中,數字 x 出...

乙個簡單的詢問 HYSBZ 5016

給你乙個長度為n的序列ai,1 i n和q組詢問,每組詢問讀入l1,r1,l2,r2,需輸出 get l,r,x 表示計算區間 l,r 中,數字x出現了多少次。input 第一行,乙個數字n,表示序列長度。第二行,n個數字,表示a1 an 第三行,乙個數字q,表示詢問個數。第4 q 3行,每行四個數...