BZOJ3533: [Sdoi2014]向量集

Posted CHADLZX

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3533: [Sdoi2014]向量集相关的知识,希望对你有一定的参考价值。

可能是我的实现姿势有问题,常数很大,不过可以卡过去.

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<iomanip>
using namespace std;
#define ll long long
#define db double 
#define up(i,j,n) for(int i=j;i<=n;i++)
#define pii pair<int,int>
#define uint unsigned int
#define FILE "dealing"
#define eps 1e-4
int read(){
	int x=0,f=1,ch=getchar();
	while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
	while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();}
	return x*f;
}
template<class T>  bool cmax(T& a,T b){return a<b?a=b,true:false;}
template<class T>  bool cmin(T& a,T b){return a>b?a=b,true:false;}
const ll maxn=1600550,limit=50100,inf=(ll)(1e18),mod=(int)1e9+7;
int n,cnt=0;
int xx[maxn],yy[maxn];
int L=0,root[maxn],Long[maxn],midd[maxn];
int fL=0,froot[maxn],fLong[maxn],fmidd[maxn];
struct vec{
	ll x,y;
	vec(ll x=0,ll y=0):x(x),y(y){}
	vec operator-(const vec& b){return vec(x-b.x,y-b.y);}
	bool operator<(const vec& b)const{return x<b.x||(x==b.x&&y<b.y);}
}ch[maxn],q[maxn<<2],fq[maxn<<2],que[maxn];
ll cro(vec a,vec b){return a.x*b.y-a.y*b.x;}
ll dot(vec a,vec b){return a.x*b.x+a.y*b.y;}
void build(int l,int r,int o){
	root[o]=++L;int tail=0;
	up(i,l,r)
		if(yy[i]>0)ch[++tail]=vec(xx[i],yy[i]);
	sort(ch+1,ch+tail+1);
	que[1]=ch[1];int top=1;
	up(i,2,tail){
		while(top>1&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--;
		que[++top]=ch[i];
	}
	int k=top;
	for(int i=tail-1;i>=1;i--){
		while(top>k&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--;
		que[++top]=ch[i];
	}
	if(!tail)top=0,k=0;
	up(i,L,L+top-1)q[i]=que[i-L+1];
	midd[o]=k;Long[o]=top;
	L=L+top-1;
	
	froot[o]=++fL;tail=0;
	up(i,l,r)if(yy[i]<=0)ch[++tail]=vec(xx[i],yy[i]);
	sort(ch+1,ch+tail+1);
	que[1]=ch[1];top=1;
	up(i,2,tail){
		while(top>1&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--;
		que[++top]=ch[i];
	}
	k=top;
	for(int i=tail-1;i>=1;i--){
		while(top>k&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--;
		que[++top]=ch[i];
	}
	if(!tail)top=0,k=0;
	up(i,fL,fL+top-1)fq[i]=que[i-fL+1];
	fLong[o]=top;fmidd[o]=k;
	fL=fL+top-1;
}
void add(int l,int r,int x,int y,int o){
	if(l>cnt||r<cnt)return;
	if(l==r){
		xx[l]=x,yy[l]=y;
		build(l,r,o);
		return;
	}
	int mid=(l+r)>>1;
	add(l,mid,x,y,o<<1);
	add(mid+1,r,x,y,o<<1|1);
	if(r==cnt)build(l,r,o);
}
ll Ans=-inf;
void divide(int x,int y,int o){
	if(root[o]+Long[o]-1<root[o])return;
	int l=root[o],r=root[o]+midd[o]-1;
	ll ans=-inf;
	while(l+3<=r){
		int mid1=(l+l+r)/3;
		ll ans1=(ll)dot(q[mid1],vec(x,y));
		int mid2=(l+r+r)/3;
		ll ans2=(ll)dot(q[mid2],vec(x,y));
		if(ans1<=ans2)l=mid1;
		else r=mid2;
	}
	up(i,l,r)cmax(ans,(ll)dot(q[i],vec(x,y)));
	cmax(Ans,ans);
	l=root[o]+midd[o]-1,r=root[o]+Long[o]-1;
	ans=-inf;
	while(l+3<=r){
		int mid1=(l+l+r)/3;
		ll ans1=(ll)dot(q[mid1],vec(x,y));
		int mid2=(l+r+r)/3;
		ll ans2=(ll)dot(q[mid2],vec(x,y));
		if(ans1<=ans2)l=mid1;
		else r=mid2;
	}
	up(i,l,r)cmax(ans,(ll)dot(q[i],vec(x,y)));
	cmax(Ans,ans);
}
void divide2(int x,int y,int o){
	if(froot[o]+fLong[o]-1<froot[o])return;
	
	int l=froot[o],r=froot[o]+fmidd[o]-1;
	ll ans=-inf;
	while(l+3<=r){
		int mid1=(l+l+r)/3;
		ll ans1=(ll)dot(fq[mid1],vec(x,y));
		int mid2=(l+r+r)/3;
		ll ans2=(ll)dot(fq[mid2],vec(x,y));
		if(ans1<ans2)l=mid1;
		else r=mid2;
	}
	up(i,l,r)cmax(ans,(ll)dot(fq[i],vec(x,y)));
	cmax(Ans,ans);
	
	l=froot[o]+fmidd[o]-1,r=froot[o]+fLong[o]-1;
	ans=-inf;
	while(l+3<=r){
		int mid1=(l+l+r)/3;
		ll ans1=(ll)dot(fq[mid1],vec(x,y));
		int mid2=(l+r+r)/3;
		ll ans2=(ll)dot(fq[mid2],vec(x,y));
		if(ans1<ans2)l=mid1;
		else r=mid2;
	}
	up(i,l,r)cmax(ans,(ll)dot(fq[i],vec(x,y)));
	cmax(Ans,ans);
}
void query(int l,int r,int x,int y,int ql,int qr,int o){
	if(l>qr||r<ql)return;
	if(l>=ql&&r<=qr){
		divide(x,y,o);
		divide2(x,y,o);
		return;
	}
	int mid=(l+r)>>1;
	query(l,mid,x,y,ql,qr,o<<1);
	query(mid+1,r,x,y,ql,qr,o<<1|1);
}
char s;
ll last=0;
int de(int x){
     if(s==‘E‘)return x;
	 return x ^ (last & 0x7fffffff);
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	n=read();char ch;scanf(" %c",&s);
	up(i,1,n){
		int x,y,l,r;
		scanf(" %c",&ch);
		if(ch==‘A‘){
			cnt++;
			x=de(read()),y=de(read());
			add(1,n,x,y,1);
		}
		if(ch==‘Q‘){
			x=de(read()),y=de(read()),l=de(read()),r=de(read());
			Ans=-inf;
			query(1,n,x,y,l,r,1);
			printf("%lld\n",last=Ans);
		}
	}
	cout<<clock()<<endl;
	return 0;
}

  

以上是关于BZOJ3533: [Sdoi2014]向量集的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3533: [Sdoi2014]向量集

BZOJ3533 [Sdoi2014]向量集 线段树 + 凸包 + 三分

BZOJ3533: [Sdoi2014]向量集

BZOJ 3533 sdoi 2014 向量集

[BZOJ3533]向量集

[SDOI2014] 向量集