Bzoj1568 [JSOI2008]Blue Mary开公司
Submit: 1025 Solved: 355
[Submit][Status][Discuss]
Description
Input
第一行 :一个整数N ,表示方案和询问的总数。 接下来N行,每行开头一个单词“Query”或“Project”。 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益。 若单词为Project,则后接两个实数S,P,表示该种设计方案第一天的收益S,以及以后每天比上一天多出的收益P。
Output
对于每一个Query,输出一个整数,表示询问的答案,并精确到整百元(以百元为单位,例如:该天最大收益为210或290时,均应该输出2)。
Sample Input
10
Project 5.10200 0.65000
Project 2.76200 1.43000
Query 4
Query 2
Project 3.80200 1.17000
Query 2
Query 3
Query 1
Project 4.58200 0.91000
Project 5.36200 0.39000
Project 5.10200 0.65000
Project 2.76200 1.43000
Query 4
Query 2
Project 3.80200 1.17000
Query 2
Query 3
Query 1
Project 4.58200 0.91000
Project 5.36200 0.39000
Sample Output
0
0
0
0
0
0
0
0
0
HINT
约定: 1 <= N <= 100000 1 <= T <=50000 0 < P < 100,| S | <= 10^6 提示:本题读写数据量可能相当巨大,请选手注意选择高效的文件读写方式。
Source
线段树 李超线段树
线段树的每个结点上存的是这个区间对应的一条线段。
更新的时候,如果新线段完全更劣,就return;如果完全更优,就交换新旧线段,继续向下update;如果部分更优,就把占优部分较多的那条线段留在这个结点,把另一条线段较优的那部分截出来,用于更新左/右子树
查询的时候,因为每一层结点都存着线段,且不能确定在查询点到底哪条更优,所以要一直查到最深层。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 using namespace std; 7 const int mxn=100010; 8 int read(){ 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();} 12 return x*f; 13 } 14 struct node{ 15 double k,b; 16 }t[mxn<<2]; 17 inline double f(double k,double b,int x){return k*(x-1)+b;} 18 void update(int L,int R,double k,double b,int l,int r,int rt){ 19 if(L<=l && r<=R){ 20 double uL=f(k,b,l),uR=f(k,b,r); 21 double aL=f(t[rt].k,t[rt].b,l),aR=f(t[rt].k,t[rt].b,r); 22 if(uL<=aL && uR<=aR)return; 23 if(uL>=aL && uR>=aR){ 24 swap(t[rt].k,k);swap(t[rt].b,b); 25 } 26 else{ 27 int mid=(l+r)>>1; 28 double um=f(k,b,mid),am=f(t[rt].k,t[rt].b,mid); 29 if(um>=am){ 30 swap(k,t[rt].k);swap(b,t[rt].b); 31 swap(uL,aL);swap(uR,aR); 32 } 33 if(uL<=aL) 34 update(mid+1,R,k,b,mid+1,r,rt<<1|1); 35 else update(l,mid,k,b,l,mid,rt<<1); 36 return; 37 } 38 } 39 if(l==r)return; 40 int mid=(l+r)>>1; 41 if(L<=mid)update(L,mid,k,b,l,mid,rt<<1); 42 if(R>mid)update(mid+1,R,k,b,mid+1,r,rt<<1|1); 43 return; 44 } 45 double ans=0.0; 46 void query(int p,int l,int r,int rt){ 47 ans=max(ans,f(t[rt].k,t[rt].b,p)); 48 if(l==r)return; 49 int mid=(l+r)>>1; 50 if(p<=mid)query(p,l,mid,rt<<1); 51 else query(p,mid+1,r,rt<<1|1); 52 return; 53 } 54 int n,T; 55 char s[10]; 56 int main(){ 57 int i,j; 58 n=read(); 59 int ed=50000; 60 for(i=1;i<=n;i++){ 61 scanf("%s",s); 62 if(s[0]=='Q'){ 63 T=read();ans=0.0; 64 query(T,1,ed,1); 65 printf("%d\n",(int)(ans/100)); 66 } 67 else{ 68 double s,p; 69 scanf("%lf%lf",&s,&p); 70 update(1,ed,p,s,1,ed,1); 71 } 72 } 73 return 0; 74 }
本文为博主原创文章,转载请注明出处。