1568: [JSOI2008]Blue Mary开公司
Time Limit: 15 Sec Memory Limit: 162 MB
Submit: 557 Solved: 192
[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
Solution
李超线段树,对于插入,相当于是在根插入,标记永久化,即标记不下推,每个点标记唯一
当插入一个新的直线,判断当前区间,即交点横坐标,以此判断优势区间,自己的理解:
至于查询,因为向下查找,所以不会有影响,复杂度$O(logn)$
可能个人理解有不对,欢迎指导
Code
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int read() { int x=0,f=1; char ch=getchar(); while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();} while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();} return x*f; } int N,M; struct LineNode { double k,b; int id; LineNode(int x0=0,int y0=0,int x1=0,int y1=0,int ID=0) { id=ID; if (x0==x1) k=0,b=max(y0,y1); else k=(double)(y0-y1)/(x0-x1),b=(double)y0-k*x0; } double getf(int x) {return k*x+b;} }; bool cmp(LineNode A,LineNode B,int x) { if (!A.id) return 1; return A.getf(x)!=B.getf(x)?A.getf(x)<B.getf(x):A.id<B.id; //比较值直线A,B在x的值,如果A<B返回1 } #define maxn 50010 LineNode tree[maxn<<2]; LineNode Query(int now,int l,int r,int x) { if (l==r) return tree[now]; int mid=(l+r)>>1; LineNode tmp; if (x<=mid) tmp=Query(now<<1,l,mid,x); else tmp=Query(now<<1|1,mid+1,r,x); return cmp(tree[now],tmp,x)?tmp:tree[now]; } void insert(int now,int l,int r,LineNode x) { if (!tree[now].id) tree[now]=x; if (cmp(tree[now],x,l)) swap(tree[now],x); if (l==r || tree[now].k==x.k) return; int mid=(l+r)>>1; double X=(tree[now].b-x.b)/(x.k-tree[now].k);//求交点,X为交点横坐标,判断下放区间 if (X<l || X>r) return; if (X<=mid) insert(now<<1,l,mid,tree[now]),tree[now]=x; else insert(now<<1|1,mid+1,r,x); } void Insert(int now,int l,int r,int L,int R,LineNode x) { if (L<=l && R>=r) {insert(now,l,r,x); return;} int mid=(l+r)>>1; if (L<=mid) Insert(now<<1,l,mid,L,R,x); if (R>mid) Insert(now<<1|1,mid+1,r,L,R,x); } int main() { M=read(); N=50000; char opt[15]; while (M--) { scanf("%s",opt); if (opt[0]==‘P‘) { double K,B; scanf("%lf%lf",&K,&B); LineNode tmp; tmp.k=B; tmp.b=K-B; tmp.id=1; Insert(1,1,N,1,N,tmp); } int x; if (opt[0]==‘Q‘) x=read(),printf("%lld\n",(long long)(Query(1,1,N,x).getf(x)/100+1e-8)); } return 0; }
参照着zky学长的模板打的...中间有好多问题,慢慢就特别相似了(捂脸)
时间: 2024-10-08 12:15:15