這是hnoi2016的day1t1;
是一道眾多cj神犇口中的水題,也是ymd 用分塊,莫隊打天下的第一站;
這個題只要數學沒有跪爛,應該還是可以看出來,
目標是要判定是否存在路徑使x,y聯通,且路上的a的最大值等於a,b的最大值等於b;
好我們先考慮暴力怎麼解決;
對於前二十分,我們考慮對於每組詢問,只加入a<=a且b<=b的邊,在用並查集判斷是否聯通以及最大值是否為a和b;
好的,那麼我們該怎麼做呢;
首先我們身在hn,那麼我們的腦海中一定要裝著兩個演算法:莫隊和cdq,這是hn的驕傲!!
其次我們要謹記網管的教導「暴力出奇蹟」,
「這題你不會,那你打個暴力就可以了嘛,暴力就可以ac嘛」;
謹記王隊長的傳奇「暴力進省隊」;
所以這題的正解就是比純暴力好一點點大暴力:分塊!!!
思想和暴力及其類似:我們把邊按照a sort,再進行分塊,再把詢問按照 b 進行排序;
1.我們對於每個塊,先把前i-1個塊中的邊全部搞出來,再把對於滿足這個塊的a(即大於等於這個塊的開頭,小於等於這個塊的結尾)的詢問全部全部搞出來。並把搞出來的邊按照b進行排序。
2.然後再列舉這些滿足a的詢問,有兩步操作,乙個是算這個塊之前的貢獻,乙個是算這個塊對當前詢問的貢獻;
3.第一步,因為前面已經按a排序了,所以前面的這些邊的a值是一定滿足詢問的a的限制的,所以我們只要把已經按照b排了序的邊判斷是否滿足詢問的b的條件再依次加入
4.第二步,因為a和b都不一定滿足要求,所以我們需要暴力對這個塊中的邊進行兩次判斷,即a和b都需要判斷,再加入這條邊;
5.並且由於滿足這個塊的詢問的a並不一定是公升序的,所以可能對於滿足的兩個詢問i,j;
biaj;這樣就會有乙個尷尬的問題,一條邊的ax可能滿足aj
6.這樣這個題目就可以ac了;
7.最後記得常數優化,cmp要打 const &,不然會gi爛;
// made by qt666
#include#include#include#include#include#include#include#define rg register
using namespace std;
const int n=100050;
int gi()
int n,m,fa[n],maxa[n],maxb[n],size[n],tot2,tot,ans[n];
int find(rg int x)
struct ac
e[n],query[n],old[n];
struct ac
add[n];
bool cmpa(const ac &a,const ac &b)
; if(x==y)
fa[x]=y;size[y]+=size[x];
maxa[y]=max(maxa[x],max(maxa[y],a));
maxb[y]=max(maxb[x],max(maxb[y],b));
}void del()
tot2=0;
}int main()
{ n=gi(),m=gi();
rg int block=(int)sqrt(m);
for(rg int i=1;i<=m;i++) e[i].x=gi(),e[i].y=gi(),e[i].a=gi(),e[i].b=gi(),e[i].id=i;
sort(e+1,e+1+m,cmpa);
rg int t=gi();
for(rg int i=1;i<=t;i++) query[i].x=gi(),query[i].y=gi(),query[i].a=gi(),query[i].b=gi(),query[i].id=i;
sort(query+1,query+1+t,cmpb);
for(rg int i=1;i<=m;i+=block)
{tot=0;
for(rg int j=1;j<=t;j++)
{ if(query[j].a>=e[i].a&&(i+block>m||query[j].a
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 最小公倍數
題目 不難發現題意就是,每條邊有兩種權值,每次詢問兩個點 u,v 問 u 到 v 是否存在一條路徑滿足第一類邊權的最大值為 a 第二類邊權的最大值為 b 乙個直觀的暴力做法就是把 a i leq a,b i leq b 的邊都加進來,看看加入這些邊後 u,v 是否聯通 如果聯通,在看看 u,v 所在...
HNOI2016 最小公倍數
分塊,並查集 對邊 a 和詢問 b 分別排序 邊分塊處理,找出當前塊內所有的詢問一起處理 對於每乙個塊的詢問 對於前面塊內的邊,a肯定比當前詢問小,所以按b排序,一條條加入並查集,直到超過詢問的b 這一步可以雙指標維護,就不用標記了 暴力遍歷該塊,找到符合要求的邊,加入並查集,同時標記 並查集判聯通...