日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【CF603E】Pastoral Oddities cdq分治+并查集

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【CF603E】Pastoral Oddities cdq分治+并查集 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【CF603E】Pastoral Oddities

題意:有n個點,依次加入m條邊權為$l_i$的無向邊,每次加入后詢問:當前圖是否存在一個生成子圖,滿足所有點的度數都是奇數。如果有,輸出這個生成子圖中邊權最大的邊的權值最小可能是多少。

$n\le 10^5,m\le 10^6,l_i\le 10^9$

題解:可以證明如果存在一個生成子圖滿足所有點度數都是奇數,當且僅當所有連通塊都有偶數個點。并且可以知道加邊一定不會使答案更劣。正解有三種:1.LCT維護最小生成樹;2.cdq分治(類似整體二分);3.線段樹(類似按時間分治)。都比較神,本人采用了第二種。

官方題解:http://codeforces.com/blog/entry/21914

大神的第二種做法的題解:https://www.cnblogs.com/galaxies/p/cf603E.html

?

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=100010; const int maxm=300010; int f[maxn],g[maxn],siz[maxn],st[maxn],ans[maxm]; int n,m,cnt,top; struct edge {int a,b,c,tim; }p[maxm],q[maxm]; bool cmp(const edge &a,const edge &b) {return (a.c==b.c)?(a.tim<b.tim):(a.c<b.c); } inline void uni(int a,int b) {int x=a,y=b,c=0,d=0;while(f[x]!=x) x=f[x],c++;while(f[y]!=y) y=f[y],d++;if(x==y) return ;if(c>d) swap(x,y),swap(a,b);cnt-=(siz[x]&1)+(siz[y]&1)-((siz[x]+siz[y])&1);siz[y]+=siz[x],f[x]=y;st[++top]=x; } inline void del(int x) {int y=f[x];siz[y]-=siz[x],f[x]=x;cnt+=(siz[x]&1)+(siz[y]&1)-((siz[x]+siz[y])&1); } void solve(int l,int r,int L,int R) {if(l>r) return ;int mid=(l+r)>>1,i,now=top,MID;for(i=l;i<=mid;i++) if(p[i].c<=L) uni(p[i].a,p[i].b);for(i=L;i<=R&&cnt;i++) if(q[i].tim<=mid) uni(q[i].a,q[i].b);MID=max(L,i-1);if(!cnt) ans[p[mid].tim]=q[MID].c;else ans[p[mid].tim]=-1;while(top>now) del(st[top--]);for(i=L;i<=MID;i++) if(q[i].tim<=l) uni(q[i].a,q[i].b);solve(l,mid-1,MID,R);while(top>now) del(st[top--]);for(i=l;i<=mid;i++) if(p[i].c<=L) uni(p[i].a,p[i].b);solve(mid+1,r,L,MID);while(top>now) del(st[top--]); } inline int rd() {int ret=0,f=1; char gc=getchar();while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();return ret*f; } int main() {n=rd(),m=rd();int i;for(i=1;i<=m;i++) p[i].a=rd(),p[i].b=rd(),p[i].c=rd(),p[i].tim=i,q[i]=p[i];sort(q+1,q+m+1,cmp);for(i=1;i<=n;i++) f[i]=i,siz[i]=1;for(i=1;i<=m;i++) p[q[i].tim].c=i;cnt=n;solve(1,m,1,m);for(i=1;i<=m;i++) printf("%d\n",ans[i]);return 0; }

轉載于:https://www.cnblogs.com/CQzhangyu/p/8595001.html

總結

以上是生活随笔為你收集整理的【CF603E】Pastoral Oddities cdq分治+并查集的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。