zoukankan      html  css  js  c++  java
  • luogu P4097 [HEOI2013]Segment

    李超线段树模板题。

    大概思路呢,就是每个区间留着一个标记(tag)表示在这个区间中点函数值最大线段的编号,然后在不停的放线段进去递归处理就行了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    const int N=100009,M=40000;
    int n,Q;
    struct LC_Tree
    {
    	int Max[M*4],cnt;
    	double K[N],B[N];
    	
    	double val(int id,int x)
    	{
    		return x*K[id]+B[id];
    	}
    	void Ins(int x,int y,int X,int Y)
    	{
    		cnt++;
    		K[cnt]=1.*(Y-y)/(X-x);
    		B[cnt]=Y-K[cnt]*X;
    	}
    	void Modify(int k,int l,int r,int id)
    	{
    		if(l==r)
    		{
    			Max[k]=val(Max[k],l)>val(id,l)?Max[k]:id;
    			return;
    		}
    		int mid=l+r>>1;
    		if(K[id]>K[Max[k]])
    		{
    			if(val(id,mid)>val(Max[k],mid))
    				Modify(k<<1,l,mid,Max[k]),Max[k]=id;
    			else
    				Modify(k<<1|1,mid+1,r,id);
    		}
    		else
    		{
    			if(val(id,mid)>val(Max[k],mid))
    				Modify(k<<1|1,mid+1,r,Max[k]),Max[k]=id;
    			else
    				Modify(k<<1,l,mid,id);
    		}
    	}
    	void change(int k,int l,int r,int x,int y,int id)
    	{
    		if(l>=x&&r<=y)
    		{
    			Modify(k,l,r,id);
    			return;
    		}
    		int mid=l+r>>1;
    		if(mid>=x)
    			change(k<<1,l,mid,x,y,id);
    		if(mid<y)
    			change(k<<1|1,mid+1,r,x,y,id);
    	}
    	double Query(int k,int l,int r,int x)
    	{
    		if(l==r)
    			return Max[k];
    		int mid=l+r>>1,qwq;
    		double ans=Max[k];
    		if(mid>=x)
    			ans=val(qwq=Query(k<<1,l,mid,x),x)>val(ans,x)?qwq:ans;
    		else
    			ans=val(qwq=Query(k<<1|1,mid+1,r,x),x)>val(ans,x)?qwq:ans;
    		return ans;
    	}
    }A;
    
    void init()
    {
    	scanf("%d",&n);
    }
    
    void work()
    {
    	int last=0,opt,x,y,X,Y;
    	for (int _=1;_<=n;_++)
    	{
    		scanf("%d",&opt);
    		if(opt==0)
    		{
    			scanf("%d",&x);
    			x=(x+last-1)%39989+1;
    			printf("%d
    ",last=A.Query(1,1,M,x));
    		}
    		else
    		{
    			scanf("%d %d %d %d",&x,&y,&X,&Y);
    			x=(x+last-1)%39989+1,y=(y+last-1)%1000000000+1;
    			X=(X+last-1)%39989+1,Y=(Y+last-1)%1000000000+1;
    			if(x>X)
    				swap(x,X),swap(y,Y);
    			A.Ins(x,y,X,Y);
    			A.change(1,1,M,x,X,A.cnt);
    		}
    	}
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    how to uninstall devkit
    asp.net中bin目录下的 dll.refresh文件
    查找2个分支的共同父节点
    Three ways to do WCF instance management
    WCF Concurrency (Single, Multiple, and Reentrant) and Throttling
    检查string是否为double
    How to hide TabPage from TabControl
    获取当前系统中的时区
    git svn cygwin_exception
    lodoop打印控制具体解释
  • 原文地址:https://www.cnblogs.com/With-penguin/p/12757400.html
Copyright © 2011-2022 走看看