zoukankan      html  css  js  c++  java
  • 【bzoj1568】 JSOI2008—Blue Mary开公司

    http://www.lydsy.com/JudgeOnline/problem.php?id=1568 (题目链接)

    题意

      在线维护若干条直线,询问一些横坐标上的最高直线的纵坐标。

    Solution

      超哥线段树=  =。可以说是标记可持久化的一个好的应用吧。

      线段树上一个节点为一个容器,可以存放一条直线。考虑插入一条直线时,当找到要插入的区间节点时,如果这个节点的容器没东西则将这条直线直接放在这个节点的容器中。否则和容器中的线段比较,保留较高部分较多的直线,将另一条直线作为新的插入直线往左儿子或者右儿子递归处理,最后到叶子节点直接比较即可。

      这样一次插入,在线段树上最多覆盖满$log$个区间,每个区间递归下去$log$层。查询时间复杂度为一个$log$。时间复杂度为$O(nlog^2n)$

    细节

      记得各种eps。

    代码

    // bzoj1568
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf (1ll<<60)
    #define eps 1e-8
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
    using namespace std;
    	
    const int lim=50000,maxn=100010;
    int n;
    char ch[100];
    
    struct seg {
    	double k,b;
    	double ch(int x) {return k*x+b;}
    }t;
    struct node {int cov;seg mx;}tr[maxn<<2];
    
    double X(seg a,seg b) {
    	return fabs(a.k-b.k)<eps ? inf : (a.b-b.b)/(b.k-a.k);
    }
    void insert(int k,int l,int r,seg g) {
    	int mid=(l+r)>>1;
    	if (!tr[k].cov) tr[k].cov=1,tr[k].mx=g;
    	else {
    		seg a1=g,a2=tr[k].mx;double x=X(a1,a2);
    		if (a1.ch(l)<a2.ch(l) || (fabs(a1.ch(l)-a2.ch(l))<eps && a1.k<a2.k)) swap(a1,a2);
    		if (x<=l || x>=r) {tr[k].mx=a1;return;}
    		if (x<=mid) tr[k].mx=a2,insert(k<<1,l,mid,a1);
    		else tr[k].mx=a1,insert(k<<1|1,mid+1,r,a2);
    	}
    }
    double query(int k,int l,int r,int x) {
    	if (l==r) return tr[k].cov ? tr[k].mx.ch(x) : 0;
    	int mid=(l+r)>>1;double t;
    	if (x<=mid) t=query(k<<1,l,mid,x);
    	else t=query(k<<1|1,mid+1,r,x);
    	return tr[k].cov ? max(t,tr[k].mx.ch(x)) : t;
    }
    
    int main() {
    	scanf("%d",&n);
    	for (int x,i=1;i<=n;i++) {
    		scanf("%s",ch);
    		if (ch[0]=='P') scanf("%lf%lf",&t.b,&t.k),insert(1,0,lim,t);
    		if (ch[0]=='Q') scanf("%d",&x),printf("%lld
    ",(LL)query(1,0,lim,x-1)/100);
    	}
    	return 0;
    }
    
  • 相关阅读:
    JAVA单例模式的实现伪代码
    Oracle提高SQL查询效率where语句条件的先后次序
    JAVA源文件中可以包含多个类
    Java 内部类、成员类、局部类、匿名类等
    下面那个情况可以终止当前线程的运行
    Java推断文本文件编码格式以及读取
    C/C++ 图像二进制存储与读取
    多路分发
    jQuery Mobile页面跳转切换的几种方式
    单机 &amp; 弱联网手游 防破解、金币改动 简单措施
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/6649498.html
Copyright © 2011-2022 走看看