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;
    }
    
  • 相关阅读:
    Python中替换的三种方法
    深入浅出:分布式和集群--转自码农翻身微信公众号
    如何把GitHub中的开源项目导入到Eclipse
    Socket Tools的使用
    LoadRunner 测试Socket接口函数说明
    Apache Jemeter 开发插件
    netstat 查看连接数
    redis缓存机制【转载】
    内存溢出OOM
    transform-translate位移
  • 原文地址:https://www.cnblogs.com/cycleke/p/5981964.html
Copyright © 2011-2022 走看看