HDU 5213 分塊 容斥

2022-05-20 10:32:00 字數 1567 閱讀 4541

給出n個數,給出m個詢問,詢問 區間[l,r] [u,v],在兩個區間內分別取乙個數,兩個的和為k的對數數量。

$k<=2*n$,$n <= 30000$

發現可以容斥簡化乙個詢問。乙個詢問的答案為 $[l,v]+(r,u)-[l,u)-(r,v]$,那麼我們離線詢問,將乙個詢問分成四個,分塊暴力就行了。

然後就是注意細節,不要發生越界,訪問錯位置之模擬較蠢的問題了。

/** @date    : 2017-09-24 19:54:55

* @filename: hdu 5213 分塊 容斥.cpp

* @platform: windows

* @author : lweleth ([email protected])

* @link :

* @version : $id$

*/#include #define ll long long

#define pii pair#define mp(x, y) make_pair((x),(y))

#define fi first

#define se second

#define pb(x) push_back((x))

#define mmg(x) memset((x), -1,sizeof(x))

#define mmf(x) memset((x),0,sizeof(x))

#define mmi(x) memset((x), inf, sizeof(x))

using namespace std;

const int inf = 0x3f3f3f3f;

const int n = 1e5 + 20;

const double eps = 1e-8;

int a[30010];

int blc[30010];

struct yuu

inline yuu(int _l, int _r, int i, int _f): l(_l), r(_r), idx(i), f(_f) {}

} b[120010];//明明是re 報的tle 有毒啊?

ll ans[30010];

ll vis[30010];

inline int cmp(yuu a, yuu b)

int main()

sort(b, b + m * 4, cmp);

mmf(ans);

mmf(vis);

ll t = 0;

int l = 1, r = 0;

for(int i = 0; i < m * 4; i++)

while(l > b[i].l)

while(r > b[i].r)

while(l < b[i].l)

ans[b[i].idx] += t * b[i].f;

//cout << t << b[i].l << b[i].r << endl;

} for(int i = 0; i < m; i++)

printf("%lld\n", ans[i]);

} return 0;

}//

hdu 5213 莫隊 容斥

題意 n個數,乙個k,m個詢問,每個詢問有 l1,r1 l2,r2 兩個區間,l1,r1 中取x l2,r2 中取y,使得x y k l1 r1 l2 r2 分析 根據容斥,f l1,r1,l2,r2 f l1,r2 f r1 1,r2 f l1,l2 1 f r1 1,l2 1 記錄下加減。這樣可...

HDU 5213 Lucky 莫隊 容斥

題意 n個數,m個詢問,每個詢問給出兩個區間,問從兩個區間內各取乙個數加起來和為k的方案數。範圍 n,m 3w 解法 3w考慮根號n解法,發現單個區間可以莫隊,兩個區間內各取可以容斥求。include include include include include include include i...

HDU5213 Lucky 容斥 莫隊

hdu5213 lucky 給出 n 個數和 k 有 m 次詢問,每次詢問區間 l1,r1 和區間 l2,r2 中分別取乙個數能相加得到 k 的方案數 可以考慮容斥把兩個區間的問題轉化成四個單區間的問題,對於原問題給的區間 l1,r1 和 l2,r2 我們記 f l,r 為區間 l,r 內能相加得到...