• 洛谷P4097 [HEOI2013]Segment(李超线段树)


    题面

    传送门

    题解

    调得咱自闭了……

    不难发现这就是个李超线段树,不过因为这里加入的是线段而不是直线,所以得把线段在线段树上对应区间内拆开之后再执行李超线段树的操作,那么复杂度就是(O(nlog^2n))

    以上是题解,以下是吐(zang)槽(hua)

    为什么我插入竖直线段的时候会出现(l=r)(l imes k+b eq r imes k+b)的情况呢……为什么我本地测会突然(RE)加了个(puts("qwq"))就能输出了呢……

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int C=-1,Z=0;
    inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
    void print(R int x){
        if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++C]=z[Z],--Z);sr[++C]='
    ';
    }
    const int M=39989,L=1e9,N=1e5+5;
    struct node{
    	node *lc,*rc;double b,k;bool flag;int id;
    	inline void ins(R double bb,R double kk,R int ii){b=bb,k=kk,id=ii,flag=1;}
    	inline double calc(const R int &x){return k*x+b;}
    }pool[N<<2],*rt;int tot;
    int n,q,id,ii,ql,qr,res,x;double b,k,bb,kk,mx;
    inline node *newnode(){return &pool[tot++];}
    void build(node* &p,int l,int r){
    	p=newnode();if(l==r)return;
    	int mid=(l+r)>>1;
    	build(p->lc,l,mid),build(p->rc,mid+1,r);
    }
    void update(node *p,int l,int r,double b,double k,int id){
    	if(ql<=l&&qr>=r){
    		if(!p->flag)return p->ins(b,k,id),void();
    		double lv1=l*k+b,rv1=r*k+b,lv2=p->calc(l),rv2=p->calc(r);
    		if(lv1<=lv2&&rv1<=rv2)return;
    		if(lv1>lv2&&rv1>rv2)return p->ins(b,k,id),void();
    		int mid=(l+r)>>1;
    		double x=(b-p->b)/(p->k-k);
    		if(lv1<=lv2){
    			if(x<=mid)bb=p->b,kk=p->k,ii=p->id,p->ins(b,k,id),update(p->lc,l,mid,bb,kk,ii);
    			else update(p->rc,mid+1,r,b,k,id);
    		}else{
    			if(x<=mid)update(p->lc,l,mid,b,k,id);
    			else bb=p->b,kk=p->k,ii=p->id,p->ins(b,k,id),update(p->rc,mid+1,r,bb,kk,ii);
    		}
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(ql<=mid)update(p->lc,l,mid,b,k,id);
    	if(qr>mid)update(p->rc,mid+1,r,b,k,id);
    }
    void query(node *p,int l,int r){
    	if(cmax(mx,p->calc(x)))res=p->id;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	x<=mid?query(p->lc,l,mid):query(p->rc,mid+1,r);
    }
    int cnt,op,val[N],ID[N];
    int main(){
    	q=read(),n=39989;
    	build(rt,1,n);
    	while(q--){
    		op=read();
    		if(op==1){
    			int x0=(read()+res-1)%n+1,y0=(read()+res-1)%L+1;
    			int x1=(read()+res-1)%n+1,y1=(read()+res-1)%L+1;
    			++cnt;
    			if(x0==x1&&cmax(val[x0],max(y0,y1))){ID[x0]=cnt;continue;}
    			if(x0>x1)swap(x0,x1),swap(y0,y1);
    			k=1.0*(y1-y0)/(x1-x0),b=y0-k*x0,id=cnt,ql=x0,qr=x1;
    			update(rt,1,n,b,k,id);
    		}else{
    			x=(read()+res-1)%n+1,mx=res=0;
    			query(rt,1,n);
    			cmax(mx,1.0*val[x])?res=ID[x]:0;
    			print(res);
    		}
    	}
    	return Ot(),0;
    }
    
  • 相关阅读:
    CodeCraft-19 and Codeforces Round #537 (Div. 2) B. Average Superhero Gang Power
    CodeCraft-19 and Codeforces Round #537 (Div. 2) A
    牛客寒假算法基础集训营1 C. 小a与星际探索
    牛客寒假算法基础集训营5 J 炫酷数学
    牛客寒假算法基础集训营5 A 炫酷双截棍
    pat 1136 A Delayed Palindrome
    pta 1140 Look-and-say Sequence (20 分)
    pta 1150 Travelling Salesman Problem (25 分)(模拟)
    2020年团体程序设计天梯赛 L3-1 那就别担心了
    2020年团体程序设计天梯赛 L2-4 网红点打卡攻略
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10621349.html
Copyright © 2020-2023  润新知