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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ4388 : JOI2012 invitation

發布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ4388 : JOI2012 invitation 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

注意到這個過程實質就是prim算法求最大生成樹的過程。

首先通過離散化+線段樹將$A+B$個點縮為上下各$O(n)$個點。

設已加入集合為$S$,未加入集合為$T$。

建立兩棵線段樹,維護所有在$T$集合中的點,以及從每個點連出去的邊。

用一個大根堆維護所有橫跨$ST$的邊。每次取出堆頂的邊,取出與這條邊相連的任意一個屬于$T$集合的點,若取不出則將這條邊刪去;否則將這個點加入$S$,并將所有連了它的邊加入堆中。

時間復雜度$O(n\log n)$。

?

#include<cstdio> #include<iostream> #include<cstdlib> #include<queue> #include<algorithm> using namespace std; typedef long long ll; typedef pair<int,int>P; const int N=100010,M=200010,T=525000,L=2000000; int C,n,i,x,y,seq[M];ll ans;bool del[N]; struct E{int a,b,c,d,t;}e[N]; priority_queue<P>Q; inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';} void NO(){puts("-1");exit(0); } inline void umax(int&a,int b){if(a<b)a=b;} struct World{ int n,m,b[N<<1]; int val[T],g[T],v[L],nxt[L],ed; inline int lower(int x){int l=1,r=m,mid,t;while(l<=r)if(b[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;return t; } inline void addx(int x,int y){b[++m]=x;b[++m]=y;} void pre(){b[++m]=1,b[++m]=n;sort(b+1,b+m+1);int _m=m;m=0;for(int i=1;i<=_m;i++)if(b[i]!=b[i-1])b[++m]=b[i]; } inline void find(int&x,int&y){x=lower(x),y=lower(y);} void cal(){for(int i=1;i<m;i++)if(b[i+1]-b[i]-1){if(!seq[i])NO();ans+=1LL*seq[i]*(b[i+1]-b[i]-1);} } void build(int x,int a,int b){val[x]=b;if(a==b)return;int mid=(a+b)>>1;build(x<<1,a,mid),build(x<<1|1,mid+1,b); } void ins(int x,int a,int b,int c,int d,int p){if(c<=a&&b<=d){v[++ed]=p;nxt[ed]=g[x];g[x]=ed;return;}int mid=(a+b)>>1;if(c<=mid)ins(x<<1,a,mid,c,d,p);if(d>mid)ins(x<<1|1,mid+1,b,c,d,p); } int ask(int x,int a,int b,int c,int d){if(c<=a&&b<=d)return val[x];int mid=(a+b)>>1,t=0;if(c<=mid)t=ask(x<<1,a,mid,c,d);if(d>mid)umax(t,ask(x<<1|1,mid+1,b,c,d));return t; } void change(int x,int a,int b,int c){for(int&i=g[x];i;i=nxt[i]){int j=v[i];if(!del[j])Q.push(P(e[j].t,j)),del[j]=1;}if(a==b){val[x]=0;return;}int mid=(a+b)>>1;if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);val[x]=max(val[x<<1],val[x<<1|1]); } }A,B; int v[T]; void build(int x,int a,int b){v[x]=0;if(a==b)return;int mid=(a+b)>>1;build(x<<1,a,mid),build(x<<1|1,mid+1,b); } void change(int x,int a,int b,int c,int d,int p){if(c<=a&&b<=d){umax(v[x],p);return;}int mid=(a+b)>>1;if(c<=mid)change(x<<1,a,mid,c,d,p);if(d>mid)change(x<<1|1,mid+1,b,c,d,p); } void dfs(int x,int a,int b){if(a==b){seq[a]=v[x];return;}int mid=(a+b)>>1;umax(v[x<<1],v[x]),umax(v[x<<1|1],v[x]);dfs(x<<1,a,mid),dfs(x<<1|1,mid+1,b); } int main(){read(A.n),read(B.n),read(C),read(n);for(i=1;i<=n;i++){read(e[i].a),read(e[i].b),read(e[i].c),read(e[i].d),read(e[i].t);A.addx(e[i].a,e[i].b);B.addx(e[i].c,e[i].d);}A.pre();for(i=1;i<=n;i++)A.find(e[i].a,e[i].b);build(1,1,A.m);for(i=1;i<=n;i++)if(e[i].a<e[i].b)change(1,1,A.m,e[i].a,e[i].b-1,e[i].t);dfs(1,1,A.m);A.cal();B.pre();for(i=1;i<=n;i++)B.find(e[i].c,e[i].d);build(1,1,B.m);for(i=1;i<=n;i++)if(e[i].c<e[i].d)change(1,1,B.m,e[i].c,e[i].d-1,e[i].t);dfs(1,1,B.m);B.cal();A.build(1,1,A.m);B.build(1,1,B.m);for(i=1;i<=n;i++){A.ins(1,1,A.m,e[i].a,e[i].b,i);B.ins(1,1,B.m,e[i].c,e[i].d,i);}A.change(1,1,A.m,1);while(!Q.empty()){x=Q.top().second;Q.pop();if(y=A.ask(1,1,A.m,e[x].a,e[x].b)){ans+=e[x].t;A.change(1,1,A.m,y);Q.push(P(e[x].t,x));continue;}if(y=B.ask(1,1,B.m,e[x].c,e[x].d)){ans+=e[x].t;B.change(1,1,B.m,y);Q.push(P(e[x].t,x));continue;}}if(A.val[1]||B.val[1])NO();return printf("%lld",ans),0; }

  

總結

以上是生活随笔為你收集整理的BZOJ4388 : JOI2012 invitation的全部內容,希望文章能夠幫你解決所遇到的問題。

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