【JZOJ5390】逗气

原创 2017年10月06日 21:56:24

Description

这里写图片描述

Solution

这题首先把绝对值拆掉,发现它是这样一个东西:bjajdi+cidi(ajci),我们发现cidi对我们求解没有影响,先去掉,然后就是这个东西ajdi+bj,于是对于每一个aj,bj,可以当作一个一次函数f(x)=ajx+bj,那么这里的di就作为自变量x。现在对于一个di要求最大值,那么也就是求当前所加入的直线与x=di这条与y轴平行线的交点的最高点。

那么我们有经典做法线段树:区间[l,r]记录在此区间内往上露出最长长度的线段(你可以理解为一束光在这个区间内从上往下照,照到长度最多的线段)(对于这题是直线),那么更新就维护区间的性质即可(如果没有则直接覆盖,有则选择向上露出长度多的那条,剩下的那条往下更新区间)。查询也很容易,就从根一直往下找这个位置取最大值就可以了。

Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 200010
#define inf 10000000000000000ll
#define ll long long
using namespace std;
struct node{
    int x,y;
    int wz;
}w1[N],w2[N];
bool cmp(node x,node y){
    return x.x<y.x;
}
struct tree{
    int l,r,o;
}tr[N];
struct line{
    int k,b;
    ll f(int x){
        return (ll)k*x+b;
    }
}ln[N];
int cc=1,tot=0;
void pdl(int v){
    if(!tr[v].l) tr[v].l=++cc;
}
void pdr(int v){
    if(!tr[v].r) tr[v].r=++cc;
}
double meet(int x,int y){
    return (ln[y].b-ln[x].b)*1.0/(ln[x].k-ln[y].k);
}
void change(int v,int l,int r,int x)
{
    if(!tr[v].o) {tr[v].o=x;return;}
    int o=tr[v].o;
    double p=meet(x,o);
    int mid=(l+r)/2;
    if(p<=l*1.0 || p>=r*1.0 || ln[x].k==ln[o].k)
    {
        if(ln[x].f(mid)>ln[o].f(mid)) tr[v].o=x;
        return;
    }
    if(p<=mid*1.0)
    {
        pdl(v);
        if(ln[x].k>ln[o].k) tr[v].o=x,change(tr[v].l,l,mid,o);
        else change(tr[v].l,l,mid,x);
    }
    else
    {
        pdr(v);
        if(ln[x].k<ln[o].k) tr[v].o=x,change(tr[v].r,mid+1,r,o);
        else change(tr[v].r,mid+1,r,x);
    }
}
ll find(int v,int l,int r,int x)
{
    if(!v) return -inf;
    int o=tr[v].o;
    if(!o) return -inf;
    ll tmp=ln[o].f(x);
    if(l==r) return tmp;
    int mid=(l+r)/2;
    if(x<=mid) return max(tmp,find(tr[v].l,l,mid,x));
    else return max(tmp,find(tr[v].r,mid+1,r,x));
}
int lf=1;
void add(int x){
    ln[++tot].k=lf*w1[x].x,ln[tot].b=w1[x].y;
}
ll z[N];
int main()
{
    freopen("gas.in","r",stdin);
    freopen("gas.out","w",stdout);
    int n,m;
    scanf("%d %d",&n,&m);
    int mx=0;
    fo(i,1,n) scanf("%d %d",&w1[i].x,&w1[i].y),mx=max(mx,max(w1[i].x,w1[i].y));
    fo(i,1,m) scanf("%d %d",&w2[i].x,&w2[i].y),w2[i].wz=i,mx=max(mx,max(w2[i].x,w2[i].y));
    sort(w1+1,w1+n+1,cmp),sort(w2+1,w2+m+1,cmp);
    int p=0;
    fo(i,1,m)
    {
        while(w1[p+1].x<=w2[i].x && p<n) p++,add(p),change(1,1,mx,tot);
        int wz=w2[i].wz;
        z[wz]=max(z[wz],find(1,1,mx,w2[i].y)-(ll)w2[i].x*w2[i].y);
    }
    lf=-1,p=n+1;
    memset(tr,0,sizeof(tr)),tot=0,cc=1;
    fd(i,m,1)
    {
        while(w1[p-1].x>=w2[i].x && p>1) p--,add(p),change(1,1,mx,tot);
        int wz=w2[i].wz;
        z[wz]=max(z[wz],find(1,1,mx,w2[i].y)+(ll)w2[i].x*w2[i].y);
    }
    fo(i,1,m) printf("%lld\n",z[i]);
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU5390 tree dfs序+线段树分层离线+字典树求异或最大值

tree Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) ...

HDU5390 tree

HDU5390 tree 题解

[JZOJ4594] Dynamic len(带修改莫队算法模板)

Description 有n个数编号从0→n-1,两种操作: Q L R:询问编号为L→R-1的数中共有多少种不同的数 M X Y:将编号为X的数改为Y 共有m个操作 Solut...

JZOJ 100041. 【NOIP2017提高A组模拟7.12】列车调度

JZOJ 100041. 【NOIP2017提高A组模拟7.12】列车调度DescriptionInputOutputSample InputSample1:3 1 2 3Sample2:9 1 3 ...

泽泽在巴西(jzoj普及组模拟第三题)(超难)

题目:题目描述泽泽帮助了英国某街道尽量减少酸雨的伤害,街道办主任非常感激他,就把他领到一扇门前,告诉他这扇门能通往好地方,具体好到什么程度要看泽泽人品。泽泽毫不犹豫地走了进去……泽泽来到了足球王国——...

【JZOJ5446】高考是不可能高考的

DescriptionSnuke 喜欢旗子. Snuke 正在将N 个旗子摆在一条线上. 第i 个旗子可以被放在位置xi 或yi 上. Snuke 认为两个旗子间的最小距离越大越好. 请你求出最...

Jzoj1020 逆序对统计 ≈ Bzoj3295 动态逆序对

Jzoj1020: Dramatic是在太菜了。最近,他学习了有关逆序对的知识,并且掌握了计算一个序列逆序对个数的高效算法,因此,他兴冲冲的跑去向YY牛炫耀。YY牛对此不屑一顾,并打击Dramat...

JZOJ 2017.12.09【NOIP提高组】模拟赛C组

T1题目描述给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示: //自己意会一下注...

jzoj2248 送快递 (很鸡儿巧的题)

(我都不好意思说这是普及组的题了) Petya和Vasya被聘为快递员。在工作日期间,他们将提供包裹到线上的不同点。根据公司的内部规定,包裹的交付必须严格按照一定的顺序进行。最初,Petya处于...

1422. 【汕头市选2012初中组】步行(walk) (jzoj)

题目:题目描述ftiasch 又开发了一个奇怪的游戏,这个游戏是这样的:有N 个格子排成一列,每个格子上有一个数字,第i 个格子的数字记为Ai。这个游戏有2 种操作: 如果现在在第i 个格子,则可以跳...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【JZOJ5390】逗气
举报原因:
原因补充:

(最多只允许输入30个字)