題目鏈結
思路:1.首先將1e9範圍內的所有l與r離散化處理,再維護乙個線段樹,每個節點儲存「該區間範圍內[l,r]的所有初始值可以通過的線段」
2.為了查詢能夠從1跑到n的最大初始值區間,我們通過並查集來判斷圖的聯通關係。即:dfs從大到小查詢每個區間時,通過已經儲存的該區間可通過邊,遍歷所有可達點,維護並查集。最後檢查1和n號節點父節點是否相同即可。
3.但是,由於查詢區間不同時,所有的節點的連通關係發生了變化,所以這裡我們的並查集並沒有壓縮優化路徑,這樣在回溯時才能還原節點的父子關係。出於時間複雜度的考慮,合併並查集時需要平衡一下以防止退化成鏈。
#include using namespace std;
const int maxn=1e5+10;
int n,m,u[maxn],v[maxn],l[maxn],r[maxn],lsh[maxn*2],cnt,ans,len[maxn*2],f[maxn*2];
vector e[8*maxn];
int getf(int x)
void unionf(int a,int b,vector&z)else
}}void build(int k,int l,int r,int x,int y,int num)
int mid=(l+r)>>1;
if(y<=mid) build(k<<1,l,mid,x,y,num);
else if(x>mid) build(k<<1|1,mid+1,r,x,y,num);
else build(k<<1,l,mid,x,mid,num),build(k<<1|1,mid+1,r,mid+1,y,num);
}void init(int x)
void dfs(int k,int l,int r)
if(getf(1)==getf(n)) ans+=lsh[r+1]-lsh[l];
else if(l!=r) dfs(k<<1,l,mid),dfs(k<<1|1,mid+1,r);
int num=tmp.size();
for(int i=0;itmp.clear();
}int main()
sort(lsh+1,lsh+cnt+1);
cnt=unique(lsh+1,lsh+cnt+1)-lsh-1;
init(n);
for(int i=1;i<=m;i++)
dfs(1,1,cnt); printf("%d\n",ans);
return 0;
}
牛客多校第八場
簽到題,可真短。題意 給n個數,對於每個連續子串行求區間內不同數字的個數的和。做法 一開始列舉每個區間的右端點i,判斷每個數字在區間左端點為1 i這個範圍內對右端點i的貢獻,然後累加答案,然後超時了。之後想到,每次變化範圍只會變乙個數字,只會改變乙個數字的貢獻,所以開了乙個sum記錄所有數字的貢獻就...
2019牛客多校第八場
求所有極大全一矩陣的個數。created by keane on 2019 8 10.include using namespace std typedef long long ll const int n 3050 int a n n int n,m char s n 每個1向下延伸 int dw...
2019牛客網多校第八場J Just Jump題解
題目鏈結 思路 補充 1.由於資料範圍達到1e7,只能通過lucas定理計算組合數。23.gu u i 受到含第i次攻擊在內,一共收到奇 偶次攻擊的情況數,再根據容斥原理,奇加偶減。這種題真是太難debug了,基本上就是照著ac 一步一步調 includeusing namespace std ty...