zoukankan      html  css  js  c++  java
  • [APIO2018] New Home

    题面在这里

    description

    在一个数轴上:
    给定(n)个商店,每个商店有一个开业时间,关门时间,坐标和销售物品的种类
    同时有(m)个询问,每个询问给你一个时间(t[i])和地点(d[i])试求在(t[i])时刻,一个住在(d[i])的人,为了买某种商品最远需要跑多长距离。

    data range

    [n,mle 3 imes 10^5,数轴长度le 10^9 ]

    solution

    (Luogu)评测机好评,我这种大力(Splay)都跑得过

    把每一家商店存在的区间看成一组在数轴上的插入,删除操作,使用(Splay)记录每家商店前一家该种类型商店的位置(pre),用(set)记一下就可以了

    询问的时候二分距离(len)问题即检查是否有一种商店不在([d[i]-len,d[i]+len])内,
    即求(min_{(d[i]+len,infty)}pre),于是记录一个最小值就可以了

    艰苦战斗

    code

    #include<bits/stdc++.h>
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<iomanip>
    #include<cstring>
    #include<complex>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<map>
    #include<set>
    //#define TEST
    #define FILE ""
    #define mp make_pair
    #define pb push_back
    #define RG register
    #define il inline
    using namespace std;
    typedef unsigned long long ull;
    typedef vector<int>VI;
    typedef long long ll;
    typedef double dd;
    const dd eps=1e-10;
    const int mod=1e9+7;
    const int N=1000010;
    const int inf=1e9+7;
    const dd pi=acos(-1);
    il ll read(){
    	RG ll data=0,w=1;RG char ch=getchar();
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
    	return data*w;
    }
    
    il void file(){
    	freopen(FILE"102","r",stdin);
    	freopen(FILE"a.out","w",stdout);
    }
    
    int n,k,q,m,ans[N];
    int x[N],t[N],a[N],b[N],l[N],y[N];
    struct operators{
    	int opt;//0表示插入一个商店,1表示询问,2表示删除一个商店
    	int pos,tim,kind;
    }Q[N];
    bool cmp(operators a,operators b){
    	if(a.tim==b.tim)return a.opt<b.opt;
    	else return a.tim<b.tim;
    }
    
    il void init(){
    	n=read();k=read();q=read();
    	for(RG int i=1;i<=n;i++){
    		x[i]=read();t[i]=read();a[i]=read();b[i]=read();
    		Q[++m]=(operators){0,x[i],a[i],t[i]};
    		Q[++m]=(operators){2,x[i],b[i],t[i]};
    	}
    	for(RG int i=1;i<=q;i++){
    		l[i]=read();y[i]=read();
    		Q[++m]=(operators){1,l[i],y[i],i};
    	}
    	sort(Q+1,Q+m+1,cmp);
    }
    
    struct store{int pos,id;};
    bool operator <(store a,store b){return a.pos<b.pos;}
    multiset<store>S[N];
    multiset<store>::iterator tmp;
    
    int tot,rt;
    int fa[N],s[2][N],pre[N],minpre[N],pos[N];
    #define isr(i) (s[1][fa[i]]==i)
    il void update(RG int i){
    	minpre[i]=pre[i];
    	if(pre[s[0][i]]&&pos[minpre[i]]>pos[minpre[s[0][i]]])
    		minpre[i]=minpre[s[0][i]];
    	if(pre[s[1][i]]&&pos[minpre[i]]>pos[minpre[s[1][i]]])
    		minpre[i]=minpre[s[1][i]];
    }
    il void rot(RG int i){
    	RG int j=fa[i],k=fa[j];
    	RG bool b=isr(i);
    	if(k)s[isr(j)][k]=i;fa[i]=k;
    	if(s[!b][i])fa[s[!b][i]]=j;s[b][j]=s[!b][i];
    	fa[j]=i;s[!b][i]=j;
    	update(j);
    }
    il void splay(int i,int a){
    	for(RG int j=fa[i];j!=a;rot(i),j=fa[i])
    		if(fa[j]!=a)isr(i)^isr(j)?rot(i):rot(j);
    	if(!a)rt=i;update(i);
    }
    
    il void insert(int p){
    	RG int i=rt,ff=0;
    	while(i){ff=i;i=s[p>pos[i]][i];}
    	if(!i)i=++tot;if(!ff)rt=i;
    	else s[p>pos[ff]][ff]=i;
    	if(ff)fa[i]=ff;pos[i]=p;
    	splay(i,0);
    }
    
    il void find(int p){
    	RG int i=rt;
    	while(s[p>pos[i]][i])
    		i=s[p>pos[i]][i];
    	splay(i,0);
    }
    
    il int Nxt(int p,bool b){
    	find(p);RG int i=rt;
    	if(pos[i]>p&&b)return rt;
    	if(pos[i]<p&&!b)return rt;
    	i=s[b][rt];while(s[!b][i])i=s[!b][i];return i;
    }
    
    il void Delete(int i){
    	splay(i,0);
    	RG int nxt=s[0][i],lst=s[1][i];
    	while(s[1][nxt])nxt=s[1][nxt];
    	while(s[0][lst])lst=s[0][lst];
     
    	splay(nxt,0);splay(lst,nxt);
    	fa[i]=s[0][lst]=0;
    	update(lst);update(nxt);
    }
    
    il int query(int l){
    	RG int L=Nxt(l,0);splay(L,0);
    	return pos[minpre[s[1][L]]];
    }
    
    il void Ins(int pos,int kind){
    	insert(pos);splay(tot,0);
    	tmp=S[kind].upper_bound((store){pos,0});
    	minpre[tot]=pre[tot]=pre[tmp->id];
    	minpre[tmp->id]=pre[tmp->id]=tot;
    	splay(tot,0);splay(tmp->id,0);
    	S[kind].insert((store){pos,tot});
    }
    il void Del(int pos,int kind){
    	tmp=S[kind].upper_bound((store){pos,0});
    	pre[tmp->id]=pre[pre[tmp->id]];splay(tmp->id,0);
    	tmp--;Delete(tmp->id);
    	S[kind].erase(tmp);
    }
    il int Qry(int pos){	
    	RG int l=0,r=100000000,mid,ret=-1;
    	while(l<=r){
    		mid=(l+r)>>1;
    		if(query(pos+mid+1)>=pos-mid)
    			ret=mid,r=mid-1;
    		else l=mid+1;
    	}
    	return ret;
    }
    
    int main()
    {
    	init();pos[0]=-inf;	
    	for(RG int i=1;i<=k;i++){
    		insert(-inf);update(tot);S[i].insert((store){-inf,tot});
    		insert(inf);S[i].insert((store){inf,tot});
    		minpre[tot]=pre[tot]=tot-1;update(tot);
    	}		
    	for(RG int i=1;i<=m;i++){
    		if(Q[i].opt==0)Ins(Q[i].pos,Q[i].kind);
    		if(Q[i].opt==1)ans[Q[i].kind]=Qry(Q[i].pos);
    		if(Q[i].opt==2)Del(Q[i].pos,Q[i].kind);
    	}
    	for(RG int i=1;i<=q;i++)printf("%d
    ",ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    [转]单倍长密钥加密和双倍长密钥加密,银联直联终端62域难点详解
    在ASP.NET MVC中支持 HttpHandler
    点滴积累【SQL Server】---SQL语句操作约束
    点滴积累【other】---Windows 7 IIS (HTTP Error 500.21
    点滴积累【C#】---验证码,ajax提交
    点滴积累【C#】---Highcharts图形统计
    点滴积累【C#】---C#实现下载word
    php无法上传大文件完美解决方案
    PHP上传遇到的问题-php 上传大文件主要涉及配置upload_max_filesize和post_max_size两个选项
    Call to undefined function pg_
  • 原文地址:https://www.cnblogs.com/cjfdf/p/9100520.html
Copyright © 2011-2022 走看看