分塊,並查集
對邊(a)和詢問(b)分別排序
邊分塊處理,找出當前塊內所有的詢問一起處理
對於每乙個塊的詢問:
對於前面塊內的邊,a肯定比當前詢問小,所以按b排序,一條條加入並查集,直到超過詢問的b(這一步可以雙指標維護,就不用標記了)
暴力遍歷該塊,找到符合要求的邊,加入並查集,同時標記
並查集判聯通,最大值,最小值,得到詢問答案
清空此次詢問帶標記的並查集操作(棧記錄),進入下乙個詢問
清空並查集,進入下乙個塊
細節:優化:
#include #define re register
// #define int long long
#define pair pair//#define file(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout);
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? eof : *p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
using namespace std;
inline int read()
while (isdigit(ch))
return f ? -x : x;
}inline string getstr()
const int n = 5e4 + 4, m = 1e5 + 5;
int n, m, q, ans[n];
struct edge
e[m];
struct query
q[n];
templateinline bool cmpa(const t &x, const t &y)
templateinline bool cmpb(const t &x, const t &y)
int fa[n], siz[n], mxa[n], mxb[n];
stack> st;
inline void init()
inline int getfa(int u)
inline void merge(int u, int v, const int &a, const int &b, const bool &del)
inline void delet()
}signed main()
; q = read();
for (re int i = 1; i <= q; ++i) q[i] = ;
sort(e + 1, e + m + 1, cmpa);
sort(q + 1, q + q + 1, cmpb);
const int len = sqrt(m * log2(n)); int siz = 0;
static int *l = new int [m / len + 5], *v = new int [m + 5];
for (re int i = 1; i <= m; i += len) l[++siz] = i;
l[siz + 1] = m + 1, e[m + 1].a = 0x7fffffff, e[m + 1].b = 0x7fffffff;
for (re int i = 1; i <= siz; ++i)
int u = getfa(q[now].fr), v = getfa(q[now].to);
if (u == v && mxa[u] == q[now].a && mxb[u] == q[now].b) ans[q[now].id] = 1;
delet();}}
for (re int i = 1; i <= q; ++i) puts(ans[i] ? "yes" : "no");
return 0;
}
HNOI2016 最小公倍數
給定乙個 n 個點 m條邊的無向圖,每條邊有兩個引數 a b q 個詢問,每個詢問給s,t,a,b,求是否存在一條 s 到 t的路徑 是 路徑 而不是 簡單路徑 使得經過的邊中am ax a bma x b n,q 50000 m 105 a,b 109 暴力的想法就是對於每個詢問,只加a qa且b...
HNOI2016 最小公倍數
這是hnoi2016的day1t1 是一道眾多cj神犇口中的水題,也是ymd 用分塊,莫隊打天下的第一站 這個題只要數學沒有跪爛,應該還是可以看出來,目標是要判定是否存在路徑使x,y聯通,且路上的a的最大值等於a,b的最大值等於b 好我們先考慮暴力怎麼解決 對於前二十分,我們考慮對於每組詢問,只加入...
HNOI2016 最小公倍數
題目 不難發現題意就是,每條邊有兩種權值,每次詢問兩個點 u,v 問 u 到 v 是否存在一條路徑滿足第一類邊權的最大值為 a 第二類邊權的最大值為 b 乙個直觀的暴力做法就是把 a i leq a,b i leq b 的邊都加進來,看看加入這些邊後 u,v 是否聯通 如果聯通,在看看 u,v 所在...