[BZOJ3165]线段树标记永久化

[BZOJ3165]

Code


#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pdd pair<double,double>
#define se second
#define fi first
using namespace std;
const int Lim=1e9;
const int mod=39989;
const int N=1e6+100;
struct line{double k,b;int id;}s[N];
int lc[N],rc[N],n,op,lastans=0,root,cnt,tot;
pdd mx[N],ret;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
bool chmax(double &a,double b){if(a<b){a=b;return 1;}return 0;}
pdd get(int x0,int x1,int y0,int y1){
	double k=1.0*(y1-y0)/(x1-x0);
	double b=1.0*y1-1.0*k*x1;
	return {k,b};
}
double cal(line a,int x){return a.k*x+a.b;}
double getpoint(line a,line b){return (a.b-b.b)/(b.k-a.k);}
void query(int k,int L,int R,int p){
	if(chmax(ret.fi,cal(s[k],p)))ret.se=s[k].id;
	if(L==R)return;
	int M=L+R>>1;
	if(p<=M)query(lc[k],L,M,p);
	else query(rc[k],M+1,R,p);
}
void insert(int &k,int L,int R,int ql,int qr,line seg){
	if(!k)k=++tot;
	int M=L+R>>1;
	if(ql<=L&&R<=qr){
		if(!s[k].id){s[k]=seg;return;}
		int p=getpoint(seg,s[k]);
		int pl = cal(s[k], L), pr = cal(s[k], R), nl = cal(seg, L), nr = cal(seg, R);
        if(pl > nl && pr > nr) return ;
        if(pl < nl && pr < nr) {s[k] = seg; return ;}
		if(pl<nl){
			if(p>M)insert(rc[k],M+1,R,M+1,R,s[k]),s[k]=seg;
			else insert(lc[k],L,M,L,M,seg);
		}else{
			if(p>M)insert(rc[k],M+1,R,M+1,R,seg);
			else insert(lc[k],L,M,L,M,s[k]),s[k]=seg;
		}return;
	}
	if(L==R)return;
	if(ql<=M)insert(lc[k],L,M,ql,qr,seg);
	if(M<qr)insert(rc[k],M+1,R,ql,qr,seg);
}
int main()
{
	//freopen("a.in","r",stdin);
	scanf("%d",&n);
	rep(i,1,n){
		scanf("%d",&op);
		if(!op){
			int x=(read()+lastans-1)%mod+1;
			ret.fi=ret.se=0.0;
			query(root,1,mod,x);
			printf("%d\n", lastans=(mx[x].fi>ret.fi?mx[x].se:ret.se));
		}else{
			int x0 = (read() + lastans - 1) % 39989 + 1, y0 = (read() + lastans - 1) % Lim + 1,
                x1 = (read() + lastans - 1) % 39989 + 1, y1 = (read() + lastans - 1) % Lim + 1;
			if(x0 > x1) swap(x0, x1), swap(y0, y1);
			if(x0==x1&&chmax(mx[x0].fi,max(y0,y1)))mx[x0].se=i;
			pdd fuck=get(x0,x1,y0,y1);
			insert(root,1,mod,x0,x1,{fuck.fi,fuck.se,++cnt});
		}
	}return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值