zoukankan      html  css  js  c++  java
  • 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
    ",last=Ans);
    		}
    	}
    	cout<<clock()<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    WCF和Socket
    MBA-数学
    80端口被占用
    linux系统root密码忘了怎么办 三种方法快速找回root密码
    px、em、rem、%、vw、wh、vm等单位有什么区别?
    知道id如何进入
    查询两个时间段间隔多久的数据
    jsp中的判断
    判断手机登陆还是电脑登陆
    配置pom.xml、spring.xml、spring-mvc.xml、spring-mybatis.xml、web.xml
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6653082.html
Copyright © 2011-2022 走看看