NOIP2012 開車旅行 SET 倍增

2021-08-04 04:55:59 字數 2888 閱讀 6531

啊,看到題:字好多。

然後就直接開始碼暴力模擬了,覺得可以預處理一下每個點可以到達的最近點和次近點,這樣大概就有50分了(然而實際有70分。。我忽略了只能往後走這一點帶來的便利,於是每一次都要找一次最近點&次近點= =果然弱啊(。・・)ノ)

暴力的過程寫的蠻。。。第一次只騙到15分= =,後來發現了bug調到35.。就開始在精度這裡卡。。。換了幾種最後終於有50了。。。【我還存了一次餘數除數hh.。。。】

去看了大牛的暴力,突然發現自己忽略了預處理。。。

暴力如下:

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define maxn 100010

using

namespace

std;

const ll inf=1e18;

int n,m;

ll x0;

ll h[maxn];

int vis[maxn];

ll sum[2];

int find(int x,int typ)

else

if(tp==minn)

else

if(tp==minn)

void solve(int st,ll limit)

else

return ;

}else

if(now==1)

else

return ;}}

}void solve1(ll x0,int ty,int hh)

else

if(sum[1] && ((double)ans0/ans1>(double)sum[0]/sum[1] || ((double)sum[1]*ans0==(double)ans1*sum[0] && h[ans]0];ans1=sum[1];ans=i;}}

printf("%d\n",ans);

}else

if(ty==2)

}void file()

int main()

scanf("%lld",&x0);

solve1(x0,1,0);

scanf("%d",&m);

for(int i=1;i<=m;i++)

return

0;}

70分就不管了,此時已經。。。

然後開始寫正解。

順道學了一下set

怎樣的呢?

我們可以把a,b分別走的兩步看成一步,就可以用st了。tt[i][j]表示i節點向後走2^j步到達的點,va[i][j],vb[i][j]分別表示此時a,b走的距離。

用set存每個點,注意是倒著存。把每個點最近點和次近點的標號和距離存下來

之後兩個詢問直接模擬就好。然後就a了

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define maxn 100010

using

namespace

std;

const ll inf=1e18;

int n,m;

ll x0;

ll h[maxn];

int vis[maxn];

struct nodet[5];

int tt[maxn][21];

ll va[maxn][21],vb[maxn][21];

setq;

mapint>mp;

ll a[maxn],b[maxn];

int fa[maxn],fb[maxn];

bool cmp(node u,node v)

sort(t+1,t+5,cmp);

a[i]=t[2].key;b[i]=t[1].key;

fa[i]=mp[t[2].h];fb[i]=mp[t[1].h];//system("pause");

// for(int j=1;j<=n;j++)

for(int j=0;j<=20;j++)

}else

if(j==1)

}else

if(tt[tt[i][j-1]][j-1])

else

break;}}

}double calc1(int s,ll limit,int typ)

}//system("pause");

if(sumb==0)return inf;

return (double)suma/(double)sumb;

}else

if(typ==2)

}//system("pause");

printf("%lld %lld\n",suma,sumb);

return

0; }

}void solve1(ll x0)

printf("%d\n",ans);

}void solve2(int s,ll x0)

void file()

int main()

pre();//system("pause");

scanf("%lld",&x0);

solve1(x0);

scanf("%d",&m);

for(int i=1;i<=m;i++)

return

0;}

noip2012 開車旅行 set 倍增

因為要快速查詢向後跳應該是哪乙個點,所以用set,迭代器左右晃一下查詢最接近的兩個元素 p選手是不是只能用平衡樹 然後用倍增記錄i節點跳2 j步後,a和b分別走的距離。具體的細節和統計答案也需要注意。include include include include include include de...

NOIp2012 開車旅行

傳送門 以後序列上的問題可以想一想倍增。s a i s b i sa i sb i sa i sb i 記錄在i ii這個位置讓a b a ba b開車到達的點。把a aa和b bb都跳一次稱為一輪。d is i j dis i j dis i j 表示從i ii跳2 j2 j 2j輪的總路程。p ...

Noip2012 開車旅行

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為hi,城市 i 和城市 j 之間的距離 d i,j 恰好是這兩個城市海拔高度之差的絕對值,即d i,j hi hj 旅行過程中...