Bzoj1568 [JSOI2008]Blue Mary开公司

Time Limit: 15 Sec  Memory Limit: 162 MB
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

Sample Output

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 }

 

posted @ 2017-05-05 19:45  SilverNebula  阅读(186)  评论(0编辑  收藏  举报
AmazingCounters.com