首页 > 代码库 > ZOJ 3606 Lazy Salesgirl
ZOJ 3606 Lazy Salesgirl
题意:
n(10^5)个客人来到商店 给出了来的时间和买东西的单价 售货员每隔w分钟会睡觉 如果客人来的时候她在睡觉就把她叫醒但是不买东西 买东西的客人的购买个数为1、2、3、1、2、3…循环 问 w为多大时 卖出的东西平均价格最高
思路:
容易想到将客人按来的时间排序 然后算出他们的间隔时间 w必为其中某个间隔时间 即枚举n个w的可能
如果我们将间隔排序 那么对于某个w 排在w前的所有人为买到东西的人 因此在枚举w的时候我们可以维护一个序列来不断的更新ans
假设已知序列a1 a2 a3 ... ax的ans等信息 现在对于新的w应该把b插入进去即可能为a1 a2 b a3 ... ax序列 那么我们发现从b开始的所有人购买东西的个数都变了 不过从a3到ax的人相对位置并没有变 于是我们可以这样计算新序列的值 newval = a1(start from 1) + b(start from 3) + a3(start from 1) 这里只举出了一种b的可能 对于其他可能也是同样道理 因此对于序列中的每个点 我们期望快速的知道这个序列start from 1、2、3的3种值 这可以利用线段树在logn内搞定
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<map> #include<set> #include<vector> #include<queue> #include<cstdlib> #include<ctime> #include<cmath> using namespace std; typedef long long LL; #define N 100010 #define L(x) (x<<1) #define R(x) ((x<<1)|1) int T,n,w; double ans; struct input{ int id,p,t; }g[N]; bool cmp1(input f1,input f2){ return f1.t<f2.t; } bool cmp2(input f1,input f2){ if(f1.t!=f2.t) return f1.t<f2.t; return f1.id<f2.id; } struct node{ LL sum[4]; }f[N<<2]; int leaf[N],cnt; void init(int l,int r,int i){ for(int j=0;j<4;j++) f[i].sum[j]=0; if(l==r){ leaf[cnt++]=i; return; } int mid=((l+r)>>1); init(l,mid,L(i)); init(mid+1,r,R(i)); } void update(int i){ int u=leaf[g[i].id]; f[u].sum[0]=1; for(int j=1;j<4;j++) f[u].sum[j]=g[i].p*j; do{ u>>=1; int left=f[L(u)].sum[0]; f[u].sum[0]=left+f[R(u)].sum[0]; for(int j=1;j<4;j++){ int tmp=(j+left)%3; if(!tmp) tmp=3; f[u].sum[j]=f[L(u)].sum[j]+f[R(u)].sum[tmp]; } }while(u!=1); } int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&g[i].p); for(int i=1;i<=n;i++) scanf("%d",&g[i].t); if(n==1){ printf("%.6f %.6f\n",(double)(g[1].t),(double)(g[1].p)); continue; } sort(g+1,g+n+1,cmp1); for(int i=n;i>=1;i--){ g[i].t-=g[i-1].t; g[i].id=i; } sort(g+1,g+n+1,cmp2); ans=-1; cnt=1; init(1,n,1); g[n+1].t=-1; for(int i=1;i<=n;i++){ update(i); if(g[i].t!=g[i+1].t){ double tmp=(double)(f[1].sum[1])/f[1].sum[0]; if(tmp>ans){ ans=tmp; w=g[i].t; } } } printf("%.6f %.6f\n",(double)(w),ans); } return 0; }
ZOJ 3606 Lazy Salesgirl
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。