zoukankan      html  css  js  c++  java
  • 【noip2012】开车旅行 [倍增]

    开车旅行

    倍增

    详细版

    可以发现每个起点出发后面选择的城市都是一定的 所以预处理出(to[i][j],da[i][j],db[i][j])表示从(i)出发小(A)和小(B)经过(2^j)轮后到达的地点、小(A)走的路程、小(B)走的路程

    预处理时询问第一近和第二近的地点用双向链表

    双向链表

    不仅记录当前元素的下一个元素((next))还记录当前元素的上一个元素((pre))

    数组版:

    int head,tail,tot;
    struct Node{
    	int value;
    	int pre,nxt;
    }node[SIZE];
    int initialize(){//新建链表 
    	tot=2;
    	head=1,tail=2;
    	node[head].nxt=tail,node[tail].pre=head;
    }
    int insert(int p,int val){//在p后插入包含数据val的新节点 
    	q=++tot;
    	node[q].value=val,node[node[q].nxt].pre=q,
    	node[q].nxt=node[p].nxt,node[p].nxt=q,node[q].pre=p; 
    }
    void remove(int p){
    	node[node[p].pre].nxt=node[p].nxt,
    	node[node[p].nxt].pre=node[p].pre;
    }
    void clear(){
    	memset(node,0,sizeof(node));
    	head=tail=tot=0;
    }
    
    struct Node{
    	int value;
    	Node *prev,next;
    };
    Node *head,*tail;
    void initialize(){
    	head=new Node(),tail=new Node();
    	head->next=tail,tail->prev=head;
    }
    void insert(Node *p,int val){
    	Node q=new Node(),q->value=val;
    	p->next->prev=q,q->next=p->next,
    	p->next=q,q->prev=p;
    }
    void remove(Node *p){
    	p->prev->next=p->next,p->next->prev=p->prev;
    }
    void recycle(){//链表内存回收 
    	while(head!=tail) head=head->next,delete head->prev;
        delete tail;
    }
    

    邻值查找:给定一个长度为(n)的序列(A)(A)中的数各不相同。对于(A)中的每一个数 (A_i),求:(min_{1≤j<i}|Ai−Aj|)

    以及令上式取到最小值的(j)(记为(P_i))。若最小值点不唯一,则选择使 AjAj 较小的那个。

    int n,id[N],pre[N],nxt[N];
    pair<int,int>ans[N];
    template<class t>void rd(t &x){
    	x=0;int w=0;char ch=0;
    	while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    	x=w?-x:x;
    }  
    
    struct node{int x,id;}a[N];
    bool cmp(node x,node y){return x.x<y.x;}
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    	rd(n);
    	for(int i=1;i<=n;++i) rd(a[i].x),a[i].id=i;
    	sort(a+1,a+n+1,cmp);a[0].x=-3000000000,a[n+1].x=3000000000;
    	for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    	for(int i=n,nw,l,r,lw,rw;i>=2;--i){
    		nw=id[i],l=pre[nw],r=nxt[nw];
    		lw=abs(a[nw].x-a[l].x),rw=abs(a[nw].x-a[r].x);
    		if(lw<=rw)  ans[i]=make_pair(lw,a[l].id);
    		else if(lw>rw) ans[i]=make_pair(rw,a[r].id);
    		pre[nxt[nw]]=pre[nw],nxt[pre[nw]]=nxt[nw];
    	}
    	for(int i=2;i<=n;++i) printf("%d %d
    ",ans[i].first,ans[i].second);
        return 0;
    }
    

    code

    struct node{int h,id;}a[N];
    bool cmp(node x,node y){return x.h<y.h;}
    
    int pos[N][2],to[N][20];
    void upd(int nw,int x){
    	ll d=abs(h[nw]-a[x].h);
    	if(dis[nw][0]>d||(dis[nw][0]==d&&a[x].h<h[pos[nw][0]])) 
    		dis[nw][1]=dis[nw][0],dis[nw][0]=d,pos[nw][1]=pos[nw][0],pos[nw][0]=a[x].id;
    	else if(dis[nw][1]>d||(dis[nw][1]==d&&a[x].h<h[pos[nw][1]]))
    		dis[nw][1]=d,pos[nw][1]=a[x].id;
    	
    }
    void erase(int x){nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x];}
    void prepa(){
    	for(int i=1,nw,l1,l2,r1,r2;i<=n;++i){
    		nw=id[i],l1=pre[nw],l2=pre[l1],r1=nxt[nw],r2=nxt[r1];
    		pos[i][0]=pos[i][1]=0,dis[i][0]=dis[i][1]=inf;
    		if(l1&&l1!=n+1) upd(i,l1);
    		if(l2&&l2!=n+1) upd(i,l2);
    		if(r1&&r1!=n+1) upd(i,r1);
    		if(r2&&r2!=n+1) upd(i,r2);
    		erase(nw);
    	}
    	for(int i=1;i<=n;++i) to[i][0]=pos[pos[i][1]][0],da[i][0]=dis[i][1],db[i][0]=dis[pos[i][1]][0];
    	for(int j=1;j<=17;++j)
    		for(int i=1;i<=n;++i)
    			to[i][j]=to[to[i][j-1]][j-1],da[i][j]=da[i][j-1]+da[to[i][j-1]][j-1],db[i][j]=db[i][j-1]+db[to[i][j-1]][j-1];
    }
    
    void query(int s,int lim,ll &A,ll &B){
    	for(int i=17;i>=0;--i)
    	if(to[s][i]&&da[s][i]+db[s][i]<=lim)
    		lim-=da[s][i]+db[s][i],A+=da[s][i],B+=db[s][i],s=to[s][i];
    	if(pos[s][1]&&dis[s][1]<=lim) A+=dis[s][1];
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    #endif
    	rd(n);
    	for(int i=1;i<=n;++i) rd(h[i]),a[i]=(node){h[i],i};
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=n;++i) id[a[i].id]=i,pre[i]=i-1,nxt[i]=i+1;
    	rd(x0),rd(m),pre[0]=nxt[n+1]=0,pre[n+1]=n,nxt[0]=1;
    	prepa();
    	ll A,B;double mn=inf,ret;int ans;
    	for(int i=1;i<=n;++i){
    		query(i,x0,A=0,B=0);
    		if(!B) continue;
    		ret=(A*1.0)/(B*1.0);
    		if(mn>ret)  mn=ret,ans=i;
    		else if(ret==mn) if(h[i]>h[ans]) ans=i;
    	}
    	printf("%d
    ",ans);
    	for(int i=1,s,lim;i<=m;++i){
    		rd(s),rd(lim),A=0,B=0;
    		query(s,lim,A,B);
    		printf("%lld %lld
    ",A,B);
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++的同名属性(没有虚拟属性)、同名普通函数、同名静态函数(没有虚拟静态函数),是否被覆盖
    linux iptable 设置实践
    Java的同名属性、同名普通函数、同名静态函数,是否被覆盖
    stdcall 函数调用过程(以delphi为例),还有负数的补码
    Delphi中各个包中包含的控件
    Windows消息理解(系统消息队列,进程消息队列,非队列消息)
    设计模式总论
    【Unity 3D】教程(1)建立场景
    Delphi主消息循环研究(Application.Run和Application.Initialize执行后的情况)
    TApplication,TForm,TControl,TComponent,TWinControl研究(博客索引)good
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11780864.html
Copyright © 2011-2022 走看看