1. 程式人生 > >bzoj1568 [JSOI2008]Blue Mary開公司

bzoj1568 [JSOI2008]Blue Mary開公司

define php ++i urn href 函數 思路 include blue

題目鏈接

https://www.lydsy.com/JudgeOnline/problem.php?id=1568
https://www.luogu.org/problemnew/show/P4254

思路

超哥線段樹模板題
若當前線段完全高於標記線段,則將當前線段進行標記
若當前線段完全低於標記線段,則將當前線段扔掉
若當前線段與標記線段有交點,考慮在上面的一部分是一個兩條線段形成的分段函數,將長的線段作為當前節點的標記,短的線段繼續下放

代碼

#include <iostream>
#include <cstdio>
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
const int N=1e5+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int tr[N<<2];
double a[N],b[N];
double f(int x,int l) {return a[x]*l+b[x];}
int cmp(int x,int y,int r) {return f(x,r)>=f(y,r);}
void modify(int l,int r,int k,int rt) {
    if(l==r) {
        if(cmp(k,tr[rt],l)) tr[rt]=k;
        return;
    }
    int mid=(l+r)>>1;
    if(a[k]>a[tr[rt]])
        if(cmp(k,tr[rt],mid))
            modify(l,mid,tr[rt],ls),tr[rt]=k;
        else
            modify(mid+1,r,k,rs);
    if(a[k]<a[tr[rt]])
        if(cmp(k,tr[rt],mid))
            modify(mid+1,r,tr[rt],rs),tr[rt]=k;
        else
            modify(l,mid,k,ls);
}
double query(int l,int r,int L,int rt) {
    if(l==r) return f(tr[rt],L);
    int mid=(l+r)>>1;
    double ans=0;
    if(L<=mid) return max(f(tr[rt],L),query(l,mid,L,ls));
    else return max(f(tr[rt],L),query(mid+1,r,L,rs));
}
int main() {
    int n=read();
    char s[10];
    for(int i=1;i<=n;++i) {
        scanf("%s",s);
        if(s[0]=='Q') {
            int id=read();
            printf("%d\n",(int)(query(1,n,id,1))/100);
        } else {
            scanf("%lf%lf",&b[i],&a[i]);
            b[i]-=a[i];
            modify(1,n,i,1);
        }
    }
    return 0;
}
/*
100
Query 30
Project 5.52800 0.96000
Query 24
Project -409.19200 18.24000
Project -209.51200 13.24800
Project -2.15200 2.88000
Query 20
Project 0.15200 2.49600
Query 34

0
0
0
2
*/

bzoj1568 [JSOI2008]Blue Mary開公司