北京集训DAY4
1 /* 2 单调队列 3 从左向右 每个点向右找一最近的且比他大, 4 从右往左枚举过来 每个点 向左找最近的且比他大 5 */ 6 #include <cmath> 7 #include <cstdio> 8 #include <cstdlib> 9 #include <iostream> 10 #include <algorithm> 11 using namespace std; 12 int n,s[50002],d[50002],ans[50002],ANS,a[50002],b[50002],r,i; 13 int main() 14 { 15 freopen("treasure.in","r",stdin); 16 freopen("treasure.out","w",stdout); 17 cin>>n; 18 for (i=1; i<=n; i++) scanf("%d%d",&a[i],&b[i]); 19 s[1]=a[1]; d[1]=1; r=1; 20 for (i=2; i<=n; i++) 21 { 22 while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; } 23 r++; 24 s[r]=a[i]; 25 d[r]=i; 26 } 27 s[1]=a[n]; d[1]=n; r=1; 28 for (i=n-1; i>=1; i--) 29 { 30 while (r!=0 && a[i]>s[r]) { ans[i]+=b[d[r]]; r--; } 31 r++; 32 s[r]=a[i]; 33 d[r]=i; 34 } 35 for (i=1; i<=n; i++) ANS=max(ANS,ans[i]); 36 cout<<ANS; 37 return 0; 38 }
1 /* 2 答案是连续的。 3 如果边长为x可行,边长x+1也一定能覆盖至少C个糖果 4 假如x不可行,边长为x-1是不可能覆盖C个糖果的。 5 二分答案。 6 l=1,r=10000, 判断mid是否可行, 可行-> 答案在[l,mid] ,不可行 -> (mid,r] 7 */ 8 #include <cmath> 9 #include <cstdio> 10 #include <cstdlib> 11 #include <iostream> 12 #include <algorithm> 13 using namespace std; 14 struct node {int x,y;} a[1005]; 15 int C,n,L,R,mid,b[1005],o,i; 16 int cmp(node i,node j) {return i.x<j.x;} 17 int CMP(int i,int j) {return i<j;} 18 bool WORK(int l,int r) 19 { 20 if (r-l+1<C) return false; o=0; 21 for (int i=l; i<=r; i++) b[++o]=a[i].y; 22 sort(b+1,b+o+1,CMP); 23 for (int i=C; i<=o; i++) 24 if (b[i]-b[i-C+1]<=mid) return true; 25 return false; 26 } 27 bool OK(int x) 28 { 29 int l=1; 30 for (int i=1; i<=n; i++) 31 { 32 if (a[i].x-a[l].x>x) 33 { 34 if (WORK(l,i-1)) return true; 35 while (a[i].x-a[l].x>x) l++; 36 } 37 } 38 if (WORK(l,n)) return true; 39 return false; 40 } 41 int main() 42 { 43 freopen("square.in","r",stdin); 44 freopen("square.out","w",stdout); 45 scanf("%d%d",&C,&n); 46 for (i=1; i<=n; i++) 47 scanf("%d%d",&a[i].x,&a[i].y); 48 sort(a+1,a+n+1,cmp); 49 L=0; R=10000; mid=(L+R)/2; 50 while (L<=R) 51 { 52 if (OK(mid)) {R=mid-1; mid=(L+R)/2;} else 53 { 54 L=mid+1; 55 mid=(L+R)/2; 56 } 57 } 58 cout<<L+1; 59 return 0; 60 }
1 /* 2 求出一个上图像和一个下图像,中间既不是最大值 3 图像的交点,又不是最小值直线的交点,可以扔掉。 4 斜率大的(速度大的),肯定最终到上面。所以我们按 5 斜率进行排序,排序后插入图像(从小到大),将属于 6 自己的位置求出,同理,下图像也可以求出。让上图 7 像和下图像不断移动,即可求出。 8 相当于单调栈。(右图中没有画圈的交点可以扔掉。) 9 这道题一开始保证跑的慢的豹子一定先跑,跑的快的 10 豹子一定后跑。 11 我们只需要记录最上方那条线和最下方那条线 12 被哪个豹子保管。 13 用 f[i]表示第 i 只豹子保管了哪个区间。 14 */ 15 #include<cstdio> 16 #include<cstring> 17 #include<cstdlib> 18 #include<cmath> 19 #include<iostream> 20 #include<algorithm> 21 22 using namespace std; 23 const long double INF=(long double)1000000000*10; 24 long double L,R,mid,ans,hh[100005]; 25 int r,rr,i,n,MAX,X,Y,cnt,vv[100005],vv2[100005]; 26 struct node2 {int t; long double l;} s[200005],S[200005]; 27 struct node {int t,v;} t[100005]; 28 int cmp(node i,node j) {return i.v<j.v || i.v==j.v && i.t>j.t;} 29 struct Node {long double x;int y,z;} p[200005]; 30 int CMP(Node i,Node j) {return i.x<j.x;} 31 long double work(int x,long double y) {return (long double)t[x].v*y-hh[x];} 32 int main() 33 { 34 freopen("chase.in","r",stdin); 35 freopen("chase.out","w",stdout); 36 while (1) 37 { 38 scanf("%d",&n); 39 // if (n==0) return 0; 40 MAX=0; 41 for (i=1; i<=n; i++) 42 { 43 scanf("%d%d",&t[i].t,&t[i].v); 44 MAX=max(MAX,t[i].t); 45 } 46 sort(t+1,t+n+1,cmp); int MIN=t[n].t; 47 for (i=n-1; i>=2; i--) 48 { 49 if (t[i].t>MIN) vv[i]=1; else 50 MIN=t[i].t,vv[i]=0; 51 } 52 for (i=1; i<=n; i++) hh[i]=(long double)t[i].t*t[i].v; 53 r=1; s[1].l=MAX; s[1].t=1; s[2].l=INF; vv[n]=0; 54 for (i=2; i<=n; i++) 55 if (!vv[i]) 56 { 57 while (r && work(i,s[r].l)>=work(s[r].t,s[r].l)) r--; 58 if (!r) {r=1; s[1].l=MAX; s[1].t=i; continue;} 59 L=s[r].l; R=s[r+1].l; mid=(L+R)/2.0; 60 for (int I=1; I<=80; I++) 61 { 62 if (work(i,mid)>=work(s[r].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;} 63 } 64 s[++r].l=mid; s[r].t=i; s[r+1].l=INF; 65 } 66 rr=1; S[1].l=MAX; S[2].l=INF; S[1].t=n; 67 MIN=t[1].t; 68 for (i=2; i<n; i++) 69 if (t[i].t<MIN) vv2[i]=1; else 70 MIN=t[i].t,vv2[i]=0; 71 for (i=n-1; i>=1; i--) 72 if (!vv2[i]) 73 { 74 while (rr && work(i,S[rr].l)<=work(S[rr].t,S[rr].l)) rr--; 75 if (!rr) {rr=1; S[1].l=MAX; S[1].t=i; continue;} 76 L=S[rr].l; R=S[rr+1].l; mid=(L+R)/2.0; 77 for (int I=1; I<=80; I++) 78 { 79 if (work(i,mid)<=work(S[rr].t,mid)) {R=mid; mid=(L+R)/2.0;} else {L=mid; mid=(L+R)/2.0;} 80 } 81 S[++rr].l=mid; S[rr].t=i; S[rr+1].l=INF; 82 } 83 cnt=0; 84 for (i=1; i<=r; i++) {p[++cnt].x=s[i].l; p[cnt].y=1; p[cnt].z=s[i].t;} 85 for (i=1; i<=rr; i++) {p[++cnt].x=S[i].l; p[cnt].y=0; p[cnt].z=S[i].t;} 86 sort(p+1,p+cnt+1,CMP); X=Y=0; ans=INF; 87 for (i=1; i<=cnt; i++) 88 { 89 if (p[i].y==1) X=p[i].z; else Y=p[i].z; 90 // printf("%.5f\n",(double)p[i].x); 91 if (X && Y) ans=min(ans,work(X,p[i].x)-work(Y,p[i].x)); 92 } 93 printf("%.2f\n",fabs((double)ans)); 94 return 0; 95 } 96 }
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现