Codeforces 853B Round #433 Div2D& Div1B Jury Meeting:差分前缀和+模拟

来源:互联网 发布:javascript代码例子 编辑:程序博客网 时间:2024/06/06 07:13

题意:有n(<=1e5)个城市和一个首都(0号城市),现在每个城市有一个选手,总共有m(<=1e5)次航班,每个航班要么从首都起飞,要么飞到首都去。每个飞机当天飞当天到。且坐飞机这一天什么也不能干,只能等飞机。每个飞机有一个花费和起飞时间。现在要把所有人集中到首都k(<=1e6)天,然后让他们各自回家。求最小花费,如果不可能实现k天或者不能回家了。或者去不了首都等等都输出-1。


题解:每个人可以先处理出一个极大可行区间,就是说我在[ dl , dr ]这段时间可以在首都呆着(保证有飞机接送),就是区间∪。然后所有人的区间取∩就是大家都在首都的最大可行区间了。如果有解,这个区间长度必须大于k。当获得了这个区间的时候,也就知道了所有的可行方案。假如一个方案是在start以及之前到达,在start+k+1以及之后离开。那么每个人显然应该选择[1 , start]时间内最便宜的飞机 和 [start+k+1 , 1e6]时间内最便宜的飞机。那么显然。。我们只需要对每个人把去和回的飞机遍历完一遍,就可以逐段确定答案了。那么这个任务交给前缀和用差分来搞。然后剩下的任务就是在可行区间内枚举答案了。


思路挺easy的。。。但是我这个菜鸡比赛时候一个多小时都没写好。。。。抠脚


Code:

#include<bits/stdc++.h>using namespace std;const int MAX = 1e5+100;const int MAXK = 1e6+100;typedef long long LL;int m,n,k;bool solved = false;vector<pair<int,int> > a[MAX],b[MAX];bool cmp(const pair<int,int> a,const pair<int,int>b){return a.first<b.first;} LL ansl[MAXK],ansr[MAXK];LL res;int ll,rr;void input(){scanf("%d%d%d",&n,&m,&k);for (int i=1;i<=m;i++){int d,f,t,c;scanf("%d%d%d%d",&d,&f,&t,&c);if (f==0){b[t].push_back(make_pair(d,c));}else{a[f].push_back(make_pair(d,c));} }}void init(){ll = -1;rr = 0x3f3f3f3f;for (int i=1;i<=n;i++){sort(a[i].begin(),a[i].end(),cmp);sort(b[i].begin(),b[i].end(),cmp);int dl = 0x3f3f3f3f;int dr = -1;for (vector<pair<int,int> >::iterator it = a[i].begin();it!=a[i].end();++it){dl = min(dl,it->first);}for (vector<pair<int,int> >::iterator it = b[i].begin();it!=b[i].end();++it){dr = max(dr,it->first);}if (dl==0x3f3f3f3f||dr==-1){solved = true;printf("-1\n");return;}ll = max (ll,dl);rr = min(rr,dr);}if (ll==-1||rr==0x3f3f3f3f){solved = true;printf("-1\n");}}void solve(){if (solved){return;}if (rr-ll-1<k){printf("-1\n");return ;}memset(ansl,0,sizeof ansl);memset(ansr,0,sizeof ansr);res = 0x3f3f3f3f3f3f3f3fLL;for (int i=1;i<=n;i++){int now = 1;int cost = 0x3f3f3f3f;for (int t = 0;t<a[i].size();++t){int temp = a[i][t].first;//cout<<"start "<<now<<" "<<temp<<" "<<cost<<endl;ansl[temp]-=cost;ansl[now]+=cost;now = temp;cost = min(cost,a[i][t].second);}ansl[(int)(1e6)+1]-=cost;ansl[now]+=cost;now =1e6;cost = 0x3f3f3f3f;for (int t = b[i].size()-1;t>=0;--t){int temp = b[i][t].first;//cout<<"end "<<temp<<" "<<now<<" "<<cost<<endl; ansr[now+1]-=cost;ansr[temp+1]+=cost;now = temp;cost = min(cost,b[i][t].second);}ansr[1]+=cost;ansr[now+1]-=cost;}for (int i=1;i<=1e6;i++){ansl[i]+=ansl[i-1];ansr[i]+=ansr[i-1];} for (int start = ll;start+k+1<=rr;start++){res = min(res,ansl[start]+ansr[start+k+1]);//cout<<"ans "<<start<<" "<<start+k+1<<" : "<<ansl[start]<<" "<<ansr[start+k+1]<<endl;}printf("%I64d\n",res);}int main(){//freopen("output.txt","w",stdout);input();init();solve();return 0;}


阅读全文
0 0
原创粉丝点击