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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CF1178H Stock Exchange

發(fā)布時(shí)間:2023/12/3 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CF1178H Stock Exchange 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

CF1178H Stock Exchange

題目描述

簡(jiǎn)要題意:給定2n2n2n個(gè)一次函數(shù)y=aix+bi(a,b>0)y=a_ix+b_i(a,b>0)y=ai?x+bi?(a,b>0),剛開始你有前nnn個(gè)函數(shù)各一個(gè),在任意時(shí)刻tttxxx函數(shù)可以轉(zhuǎn)換為yyy函數(shù)當(dāng)且僅當(dāng)axt+bx>=ayt+bya_xt+b_x>=a_yt+b_yax?t+bx?>=ay?t+by?,最后要獲得n+1...2nn+1...2nn+1...2n的函數(shù)各一個(gè),求完成時(shí)刻最小的前提下轉(zhuǎn)換次數(shù)的最小值。

Solution

顯然最后的方案需要1...n1...n1...nn+1...2nn+1...2nn+1...2n形成完美匹配。
有一個(gè)重要的性質(zhì):
一定存在一個(gè)最優(yōu)方案使得每一個(gè)匹配的中轉(zhuǎn)點(diǎn)唯一,且只在000時(shí)刻和ttt時(shí)刻進(jìn)行交換。(顯然對(duì)于某一匹配x?>yx->yx?>y的轉(zhuǎn)化方案{x,z1,z2...zk,y}\{x,z_1,z_2...z_k,y\}{x,z1?,z2?...zk?,y}來說,最多只需要取xxx,yyy,和一個(gè){z1...zk}\{z_1...z_k\}{z1?...zk?}中斜率最大的zmaxaz_{maxa}zmaxa?即可)

因此對(duì)于第一問,考慮二分答案完成時(shí)刻ttt,每一個(gè)1..n1..n1..n的函數(shù)在000時(shí)刻先貪心地轉(zhuǎn)化為能轉(zhuǎn)化的在ttt時(shí)刻最大的函數(shù)作為中轉(zhuǎn)點(diǎn),然后再考慮ttt時(shí)刻時(shí)能否通過這些最優(yōu)中轉(zhuǎn)點(diǎn)匹配出所有的n+1...2nn+1...2nn+1...2n的函數(shù)。

對(duì)于第二問,考慮費(fèi)用流,把每一個(gè)點(diǎn)iii拆成iiii+2ni+2ni+2n,從SSS1..n1..n1..n連一條(flow=1,cost=0)(flow=1,cost=0)(flow=1,cost=0)的邊,從n+1...2nn+1...2nn+1...2nTTT連一條(1,0)(1,0)(1,0)的邊,從iiii+2ni+2ni+2n連一條(INF,0)(INF,0)(INF,0)的邊,然后對(duì)于能在000時(shí)刻轉(zhuǎn)化的i?>ji->ji?>j,連一條(INF,1)(INF,1)(INF,1)的邊,在ttt時(shí)刻也做一次這樣的操作。

但是這樣的邊數(shù)是O(n2)O(n^2)O(n2),超過了16M16M16M的空間限制。
我們發(fā)現(xiàn)對(duì)于iii來說,它可以轉(zhuǎn)化的點(diǎn)是一段按bib_ibi?排序的前綴,所以不需要每個(gè)i?>ji->ji?>j都連邊了。

設(shè)排序之后的編號(hào)idiid_iidi?,新建i+4ni+4ni+4n的點(diǎn),從idi+4nid_i+4nidi?+4nidi?1+4nid_{i-1}+4nidi?1?+4n連一條(INF,0)(INF,0)(INF,0)的邊,再?gòu)?span id="ozvdkddzhkzd" class="katex--inline">idiid_iidi?idi+4nid_i+4nidi?+4n連一條(INF,1)(INF,1)(INF,1)的邊。

這樣一來,i?>ji->ji?>j就可以通過一層一層的價(jià)格下降得到了。然后對(duì)于i+2ni+2ni+2n的點(diǎn)也新建i+6ni+6ni+6n按上述方法連邊即可。

Code

#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <cassert> #include <string.h> //#include <unordered_set> //#include <unordered_map> //#include <bits/stdc++.h>#define MP(A,B) make_pair(A,B) #define PB(A) push_back(A) #define SIZE(A) ((int)A.size()) #define LEN(A) ((int)A.length()) #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define fi first #define se secondusing namespace std;template<typename T>inline bool upmin(T &x,T y) { return y<x?x=y,1:0; } template<typename T>inline bool upmax(T &x,T y) { return x<y?x=y,1:0; }typedef long long ll; typedef unsigned long long ull; typedef long double lod; typedef pair<int,int> PR; typedef vector<int> VI;const lod eps=1e-11; const lod pi=acos(-1); const int oo=1<<30; const ll loo=1ll<<62; const int mods=998244353; const int MAXN=4405; const int MAXM=MAXN<<6; const int INF=0x3f3f3f3f;//1061109567 /*--------------------------------------------------------------------*/ inline int read() {int f=1,x=0; char c=getchar();while (c<'0'||c>'9') { if (c=='-') f=-1; c=getchar(); }while (c>='0'&&c<='9') { x=(x<<3)+(x<<1)+(c^48); c=getchar(); }return x*f; } queue<int> que; ll c[MAXN],to[MAXN]; pair<ll,ll> a[MAXN]; int n,nn,vnum,edgenum=1,id0[MAXN],idt[MAXN],t,S,T; int flow[MAXN<<2],dist[MAXN<<2],vis[MAXN<<2]; int head[MAXN<<2],pre[MAXN<<2],from[MAXN<<2]; struct enode{ int to,nxt,f,c; } e[MAXM];int compare0(int x,int y) { return (a[x].se<a[y].se)||(a[x].se==a[y].se&&a[x].fi>a[y].fi); } int comparet(int x,int y) { return a[x].fi*t+a[x].se<a[y].fi*t+a[y].se; } bool check(int x) {t=x;for (int i=1;i<=nn;i++) c[i]=a[i].fi*t+a[i].se;for (int i=1,k=1;i<=nn;i++){if (c[id0[i]]>c[id0[k]]) k=i;to[id0[i]]=c[id0[k]];}sort(to+1,to+n+1);if (t==1e9)for (int i=1;i<=nn;i++) cout<<id0[i]<<endl;sort(idt+1,idt+nn+1,comparet);for (int i=1,now=1;i<=nn;i++) {if (idt[i]<=n) continue;if (to[now]<c[idt[i]]) return 0;else now++;}return 1; } int solve1() {int l=0,r=1e9;while (l<r){int mid=(l+r)>>1;if (check(mid)) r=mid;else l=mid+1;}return r; }void add(int u,int v,int f,int c) { // cout<<u<<" "<<v<<" "<<f<<" "<<c<<endl;e[++edgenum]=(enode){v,head[u],f, c},head[u]=edgenum;e[++edgenum]=(enode){u,head[v],0,-c},head[v]=edgenum; } void build() //這里把值相同的i+4n合并成了一個(gè)點(diǎn),效果相同,空間壓縮之后會(huì)更小一些,i+6n同理。 {S=nn<<1|1,T=vnum=S+1;for (int i=1;i<=n;i++) add(S,i,1,0);for (int i=n+1;i<=nn;i++) add(i+nn,T,1,0);for (int i=1;i<=nn;i++) add(i,i+nn,INF,0);for (int i=1;i<=nn;i++) c[i]=a[i].se;for (int i=1,j;i<=nn;i=j+1){j=i,vnum++;while (c[id0[i]]==c[id0[j+1]]) j++;for (int k=i;k<=j;k++) add(id0[k],vnum,INF,1),add(vnum,id0[k],INF,0);if (i>1) add(vnum,vnum-1,INF,0);}for (int i=1;i<=nn;i++) c[i]=a[i].fi*t+a[i].se;for (int i=1,j;i<=nn;i=j+1){j=i,vnum++;while (c[idt[i]]==c[idt[j+1]]) j++;for (int k=i;k<=j;k++) add(idt[k]+nn,vnum,INF,1),add(vnum,idt[k]+nn,INF,0);if (i>1) add(vnum,vnum-1,INF,0);} }int bfs() {for (int i=1;i<=vnum;i++) dist[i]=INF,flow[i]=vis[i]=0;dist[S]=0,flow[S]=INF,vis[S]=1,que.push(S);while (!que.empty()){int u=que.front(); que.pop(); // cout<<u<<":"<<dist[u]<<" "<<flow[u]<<endl;for (int i=head[u];i;i=e[i].nxt){int v=e[i].to,f=e[i].f,c=e[i].c;if (!f||dist[u]+e[i].c>=dist[v]) continue;pre[v]=u,from[v]=i;flow[v]=min(flow[u],f);dist[v]=dist[u]+e[i].c;if (!vis[v]) vis[v]=1,que.push(v);}vis[u]=0;}return flow[T]; } int MCMF() {int ans=0;while (bfs()){ans+=dist[T]*flow[T];for (int p=T;p!=S;p=pre[p])e[from[p]].f-=flow[T],e[from[p]^1].f+=flow[T];}return ans; } int main() {n=read(),nn=n+n;for (int i=1;i<=nn;i++) a[i].fi=read(),a[i].se=read(),id0[i]=idt[i]=i;sort(id0+1,id0+nn+1,compare0);t=solve1();if (!check(t)) { puts("-1"); return 0; } printf("%d ",t);sort(idt+1,idt+nn,comparet);build();int ans=MCMF();printf("%d\n",ans);return 0; }

總結(jié)

以上是生活随笔為你收集整理的CF1178H Stock Exchange的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。