zoukankan      html  css  js  c++  java
  • noip2012 开车旅行

    此题100分的解法就是先预处理出每个点的下一个点之后倍增就好了。其实并没有太大难度。

    pbihao用双向链表写过了此题。在本地上我treap狂操他,but在rqnoj上,我依靠反复提交才A掉此题(最后一组数据为999ms)。treap好看脸啊。

    #include <ctime>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 100005
    #define inf (1LL<<60)
    #define ll long long
    #define pli pair<long long,int>
    #define pll pair<long long,long long>
    #define FI "drive"
    int nxt[N][17],da[N][17],db[N][17],na[N],nb[N],H[N];
    int ina; char inc,inb[1<<16],*ins=inb,*ine=inb; bool insign;
    #define getc() ((ins==ine&&(ine=(ins=inb)+fread(inb,1,1<<16,stdin),ins==ine))?EOF:*ins++)
    inline int geti() {
        for(insign=false;(inc=getc())<'0'||inc>'9';insign|=inc=='-');
        for(ina=inc-'0';(inc=getc())>='0'&&inc<='9';ina=(ina<<3)+(ina<<1)+inc-'0');
    	return insign?-ina:ina;
    }
    ll iabs_t;
    #define iabs(a) ((iabs_t=(a))<0?-iabs_t:iabs_t)
    inline void cal(int s,int x,int &t1,int &t2) {
    	t1=t2=0;
    	for(int i=14;~i;--i)
    		if(nxt[s][i]&&t1+da[s][i]+t2+db[s][i]<=x){
    			t1+=da[s][i],t2+=db[s][i];
    			s=nxt[s][i];
    		}
    }
    int totnode,ch[2][N],r[N],root,id[N]; ll v[N];
    inline void rot(int &u,int d) {
    	int t=ch[d^1][u]; ch[d^1][u]=ch[d][t];
    	ch[d][t]=u; u=t;
    }
    void Ins(int &u,const ll&val,int idx) {
    	if(!u){
    		u=++totnode;v[u]=val,r[u]=rand(),id[u]=idx;
    		ch[0][u]=ch[1][u]=0; return;
    	}
    	int k=val<v[u]?0:1;
    	Ins(ch[k][u],val,idx);
    	if(r[ch[k][u]]>r[u]) rot(u,k^1);
    }
    inline int find(int val) {
    	int u=root;
    	while(u) {
    		if(v[u]==val) return u;
    		u=ch[v[u]<val][u];
    	}return 0;
    }
    int pred(int u,const ll&val) {
    	if(!u) return -1;
    	if(val<=v[u]) return pred(ch[0][u],val);
    	int t=pred(ch[1][u],val); if(t<0) t=u;
    	return t;
    }
    int succ(int u,const ll&val) {
    	if(!u) return -1;
        if(val>=v[u]) return succ(ch[1][u],val);
    	int t=succ(ch[0][u],val); if(t<0) t=u;
    	return t;
    }
    int main() {
    	freopen(FI".in","r",stdin); freopen(FI".out","w",stdout);
    	int n,i,j,s,x,m; pll t[5]; root=totnode=0;
    	for(n=geti(),i=1;i<=n;++i) H[i]=geti(); srand(time(NULL));
    	Ins(root,inf,0); Ins(root,-inf,0);
    	for(i=n;i;--i) { Ins(root,H[i],i);
    		t[1].second=v[pred(root,H[i])],t[2].second=v[succ(root,H[i])];
    		if(t[1].second>-inf) t[3].second=v[pred(root,t[1].second)];
    		else t[3].second=-inf;
    		if(t[2].second<inf) t[4].second=v[succ(root,t[2].second)];
    		else t[4].second=inf;
    		for(j=1;j<5;++j) t[j].first=iabs(t[j].second-H[i]);
    		sort(t+1,t+5);
    		na[i]=id[find(t[2].second)],nb[i]=id[find(t[1].second)];
    		(na[i])?da[i][0]=t[2].first:1;
    		(nb[na[i]])?db[i][1]=iabs(H[na[i]]-H[nb[na[i]]]),da[i][1]=t[2].first:1;
    		nxt[i][0]=na[i],nxt[i][1]=nb[na[i]];
    		for(j=2;j<15;++j)
    			if(nxt[nxt[i][j-1]][j-1]) {
    				nxt[i][j]=nxt[nxt[i][j-1]][j-1];
    				da[i][j]=da[i][j-1]+da[nxt[i][j-1]][j-1];
    				db[i][j]=db[i][j-1]+db[nxt[i][j-1]][j-1];
    			}else break;
    	}
    	int t1,t2; x=geti(); double mi=inf,_t;
    	for(i=1;i<=n;++i) {
    		cal(i,x,t1,t2);
    		_t=t2?(double)t1/t2:1e60;
    		if(_t<mi||(_t==mi&&H[j]<H[i])) j=i,mi=_t;
    	}printf("%d
    ",j);
    	for(m=geti();m;--m) {
    		s=geti(),x=geti();
    		cal(s,x,t1,t2);
    		printf("%d %d
    ",t1,t2);
    	}return 0;
    }
    

    update:今天写了一份用指针的,快了好多。

    #include <ctime>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define inf (1LL<<60)
    #define ll long long
    #define pli pair<long long,int>
    #define pll pair<long long,long long>
    char INB[1<<16],*INS=INB,*INE=INB;
    #define getc() (INS==INE&&(INE=(INS=INB)+fread(INB,1,1<<16,stdin),INS==INE)?EOF:*INS++)
    inline int geti() {
    	register int a; register char c,f=0;
    	while(c=getc(),c<'0')f|=c=='-';a=c-'0';
    	while(c=getc(),'-'<c)a=(a<<3)+(a<<1)+c-'0';
    	return f?-a:a;
    }
    ll ibs_t;
    #define ibs(a) ((ibs_t=(a))<0?-ibs_t:ibs_t)
    /*template*/
    #define N 100005
    int nxt[17][N],da[17][N],db[17][N],na[N],nb[N],H[N];
    inline void cal(int s,int x,int&t1,int&t2) {
    	t1=t2=0;
    	for(register int i=16;~i;--i)
    		if(nxt[i][s]&&t1+da[i][s]+t2+db[i][s]<=x) {
    			t1+=da[i][s];
    			t2+=db[i][s];
    			s=nxt[i][s];
    		}
    }
    struct node{
    	int r,id; ll v;
    	node*ch[2];
    }CD[N],*cd=CD,*root=NULL;
    inline void rot(node*(&u),const int&d) {
    	node*t=u->ch[d^1];u->ch[d^1]=t->ch[d];
    	t->ch[d]=u; u=t;
    }
    void ins(node*(&u),const ll&val,const int&idx) {
    	if(!u) {
    		u=cd++; u->v=val,u->id=idx,u->r=rand();
    		u->ch[0]=u->ch[1]=NULL; return;
    	}
    	int k=val<u->v?0:1;
    	ins(u->ch[k],val,idx);
    	if(u->ch[k]->r>u->r) rot(u,k^1);
    }
    inline node*find(const ll&val) {
    	node*u=root;
    	while(u) {
    		if(u->v==val) return u;
    		u=u->ch[u->v<val];
    	}return NULL;
    }
    inline node*pred(const ll&val) {
    	node*u=root,*r=NULL;
    	while(u){
    		if(u->v<val) r=u,u=u->ch[1];
    		else u=u->ch[0];
    	}
    	return r;
    }
    inline node*succ(const ll&val) {
    	node*u=root,*r=NULL;
    	while(u) {
    		if(val<u->v) r=u,u=u->ch[0];
    		else u=u->ch[1];
    	}
    	return r;
    }
    int main() {
    	register int n,i,j,s,x,m; pll t[5];
    	for(n=geti(),i=1;i<=n;++i) H[i]=geti();
    	srand(time(NULL));
    	ins(root,inf,0); ins(root,-inf,0);
    	for(i=n;i;--i) {
    		ins(root,H[i],i);
    		t[1].second=pred(H[i])->v,t[2].second=succ(H[i])->v;
    		if(t[1].second>-inf) t[3].second=pred(t[1].second)->v;
    		else t[3].second=-inf;
    		if(t[2].second<inf) t[4].second=succ(t[2].second)->v;
    		else t[4].second=inf;
    		for(j=1;j<5;++j) t[j].first=ibs(t[j].second-H[i]);
    		sort(t+1,t+5);
    		if(nxt[0][i]=na[i]=find(t[2].second)->id) da[0][i]=t[2].first;
    		nb[i]=find(t[1].second)->id;
    		if(nxt[1][i]=nb[na[i]]) db[1][i]=ibs(H[na[i]]-H[nb[na[i]]]),da[1][i]=t[2].first;
    		for(j=2;j^17;++j)
    			if(nxt[j][i]=nxt[j-1][nxt[j-1][i]]) {
    				da[j][i]=da[j-1][i]+da[j-1][nxt[j-1][i]];
    				db[j][i]=db[j-1][i]+db[j-1][nxt[j-1][i]];
    			}else break;
    	}
    	int t1,t2; x=geti(); double mi=inf,_t;
    	for(i=1;i<=n;++i) {
    		cal(i,x,t1,t2);
    		_t=t2?(double)t1/t2:1e60;
    		if(_t<mi||(_t==mi&&H[j]<H[i])) j=i,mi=_t;
    	}printf("%d
    ",j);
    	for(m=geti();m;--m) {
    		s=geti(),x=geti();
    		cal(s,x,t1,t2);
    		printf("%d %d
    ",t1,t2);
    	}return 0;
    }
    
  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/cycleke/p/5981964.html
Copyright © 2011-2022 走看看