給出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 內能相加得到...