COCI 2011/2012 CONTEST #3
来源:互联网 发布:选秀是网络词吗 编辑:程序博客网 时间:2024/06/12 20:33
题意:
一个工厂制造产品,有N个流程。第i个流程的时间系数是Ti。有M个产品要制造,第i个产品的容易程度是Fi。一个产品j,在流程i所需时间为TiFj。流程顺序不可颠倒,产品也必须按给定的顺序制作。一旦一个流程完成,就交给下一个流程。此时,下一个流程必须是空闲的,不然就会出错。问完成所有产品需要的时间。
数据满足1 ≤ N ≤ 100000,1 ≤ M ≤ 100000。
(翻译来自卓亮wc ppt)
分析题目,容易想到按顺序考虑每个产品,需要用o(n)时间与前一产品判断是否冲突并取最早时间,总复杂度为o(nm),考虑判断条件设bi为i开始时间,si为ti前缀和,我们是想满足此式:
b[j+1]-bj>=max(fj*s[k+1]-f[j+1]*sk),若想让b[j+1]尽量小,则等于右式即可,现在问题转化为求右式。
观察式子,与叉积很像,将同类式子合并则是(f[j],f[j+1])X(s[k],s[k+1]),由于(s[k],s[k+1])是静态的,所以其实是每次用向量(f[j],f[j+1])询问s点集中的叉积最大点(正叉积中最远点),我们可以预处理上凸壳,在上凸壳二分转折点(斜率最近点),即为距向量(f[j],f[j+1])最远点。
#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>struct point{ long long x,y;}a[200000];int n,m,t,k,st[200000];long long s[200000],f[200000],b[200000],ans;long long max(long long x,long long y) {return (x>y) ? x : y;}long long cross(point e,point r) {return (e.x*r.y-e.y*r.x);}long long search(int x,int y){ int l,r,mid; long long sum=0; point e,u; e.x=x,e.y=y; //e.x=-x,e.y=-y; (cross(e,u)>0) for (l=k+1,r=t;l<=r;) { mid=(l+r)>>1; u.x=a[st[mid]].x-a[st[mid-1]].x; u.y=a[st[mid]].y-a[st[mid-1]].y; if (cross(e,u)>0) l=mid+1;else r=mid-1; } sum=max(max(cross(e,a[st[l-1]]),max(cross(e,a[st[l]]),cross(e,a[st[l+1]]))),sum); return sum;}int check(int x,int y,int z){ point e,r; e.x=a[z].x-a[x].x,e.y=a[z].y-a[x].y; r.x=a[y].x-a[x].x,r.y=a[y].y-a[x].y; long long pd=cross(e,r); if (pd>=0) return 1; return 0; }void init(){ int i; long long sum; scanf("%d%d\n",&n,&m); for (i=1;i<=n;i++) scanf("%d\n",&s[i]); for (i=1;i<=m;i++) scanf("%d\n",&f[i]); for (i=1;i<=n;i++) s[i]=s[i-1]+s[i],a[i].x=s[i-1],a[i].y=s[i]; for (st[t=1]=1,i=2;i<=n;i++) { for (;(t>1)&&(check(st[t-1],st[t],i));t--) ;st[++t]=i; } for (k=t,i=n-1;i>=1;i--){ for (;(t>k)&&(check(st[t-1],st[t],i));t--) ;st[++t]=i; } for (b[1]=0,i=2;i<=m;i++) sum=search(f[i-1],f[i]),b[i]=sum+b[i-1]; ans=b[m]+f[m]*s[n]; printf("%I64d\n",ans);}int main(){ freopen("traka.in","r",stdin); freopen("traka.out","w",stdout); init(); return 0;}/* for (l=2,r=k;l<=r;) { mid=(l+r)>>1; r.x=a[st[mid]].x-a[st[mid-1]].x; r.y=a[st[mid]].y-a[st[mid-1]].y; if (cross(e,r)<0) l=mid+1;else r=mid-1; } sum=max(cross(e,a[st[l-1]]),max(cross(e,a[st[l]])),cross(e,a[st[l+1]]));*/
- COCI 2011/2012 CONTEST #3
- COCI 2011/2012 Contest#2(TOJ4484 FUNKCIJA)
- Ljutnja COCI 2010/2011 CONTEST #1-4
- dlut1002&&COCI 2012/2013 Contest#1 F7
- COCI CONTEST #3 29.11.2014 STROJOPIS
- COCI CONTEST #3 29.11.2014 HONI
- COCI CONTEST #3 29.11.2014 STOGOVI
- COCI CONTEST #3 29.11.2014 DOM
- COCI CONTEST #3 29.11.2014 SILUETA
- COCI CONTEST #3 29.11.2014 T1 STROJOPIS
- COCI CONTEST #3 29.11.2014 T2 DOM
- COCI CONTEST #3 29.11.2014 T3 SILUETA
- COCI CONTEST #3 29.11.2014 T4 HONI
- COCI CONTEST #3 29.11.2014 T5 STOGOVI
- COCI CONTEST #3 29.11.2014 T6 KAMIONI
- COCI CONTEST #3 29.11.2014 KAMIONI
- COCI CONTEST #3 29.11.2014 考后总结
- COCI CONTEST #3 29.11.2014 考后总结
- 深入解析Spring
- delphi xe2 IDE Code editor 新特性
- Max row size for Sybase
- windows IP Control validation
- 双系统重装win7重新加载Ubuntu
- COCI 2011/2012 CONTEST #3
- NXP IP-Camera ASC8051
- mac IP Control validation
- SEH转换为C++ Exception
- Sort list QTableWidget click on the head
- 音乐感知之初
- Java字符串编码
- How can I insert a checkbox into the header of my view?
- 简单有效的SQL 存储过程移植方案(1)——从Sybase 到DB2