日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

NOIP模拟测试24「star way to hevaen·lost my music」

發布時間:2023/12/2 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 NOIP模拟测试24「star way to hevaen·lost my music」 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

star way to heaven

題解

大致嘗試了一下并查集,記憶化搜索,最小生成樹

最小生成樹是正解,跑最小生成樹然后找到最大的值

歐幾里德距離最小生成樹學習

prim楞跑

至于為什么跑最小生成樹不是跑最大生成樹,你跑最大生成樹連的邊可能會^%$&$%!#

感性理解手膜吧,我理解但說不清楚,稍微手膜就出來了,你可以舉出一萬種反例

代碼實現細節比較多,技巧也比較多

注意邊界處理,我們可以以一個邊界為0,另一個邊界權值為m,比較上下邊界時不用再比較橫坐標

#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1010010 double cal(ll x1,ll y1,ll x2,ll y2){return sqrt((double)((x1-x2)*(x1-x2))+(double)((y1-y2)*(y1-y2))); } ll n,m,k; double ans; ll x[A],y[A]; double dis[A]; bool vis[A]; int main(){scanf("%lld%lld%lld",&n,&m,&k);for(ll i=1;i<=k;i++){scanf("%lld%lld",&x[i],&y[i]);dis[i]=y[i];}dis[k+1]=m;while(1){ll mi=0;for(ll j=1;j<=k+1;j++)if(!vis[j]&&(mi==0||dis[j]<dis[mi]))mi=j; // printf("mi=%lld\n",mi);ans=max(ans,dis[mi]);vis[mi]=1;if(mi==k+1){printf("%.10lf\n",ans/2);return 0;}for(ll j=1;j<=k;j++)dis[j]=min(dis[j],cal(x[j],y[j],x[mi],y[mi]));dis[k+1]=min(dis[k+1],(double)(m-y[mi]));} } 代碼

lost my music

題解

題目中說的很明顯是一個斜率單調棧維護一下

然而這是樹上問題,你暴力退棧你會被卡成$n^2$于是我又學習了一下可持久化棧

可持久化棧學習

我用的是二分方法,好理解又好打

大致就是$dfs$時傳一個$top$指針,然后你每次找到符合祖先鏈且斜率最大的地方,每次向下搜時只需要將當前對應位置棧設為$x$然后再回溯

這樣我們就可以不用退棧

直接口胡肯定不能理解

| |<---你當前棧頂指向

| |

| |<---符合的位置,你只需要將當前棧指針指向當前,,,,,最后再回溯即可

| |

| |

或者換種方式理解

維護凸包

你若當前可以更新那么賦成當前值斜率更新更大

代碼實現

void dfs(ll x,ll pre,ll de,ll top){deep[x]=de;ll k=get(x,top)+1,t1=sta[k],t2=sta[k-1];if(x==1) k=1;ans[x]=-1.0*(cal(t2,x));sta[k]=x;for(ll i=head[x];i;i=nxt[i]){ll y=ver[i];if(y==pre) continue;dfs(y,x,de+1,k);}sta[k]=t1; }

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1010101 ll n,tot; double ans[A]; ll deep[A],head[A],nxt[A],ver[A],c[A],sta[A]; void add(ll x,ll y){nxt[++tot]=head[x],head[x]=tot,ver[tot]=y; } double cal(ll x,ll y){return (double)(c[x]-c[y])/(1.0*(double)(deep[x]-deep[y])); } ll get(ll x,ll h){ll l=2,r=h,mid;double k1,k2;while(l<=r){mid=(l+r)>>1;k1=-1.0*(cal(sta[mid],sta[mid-1]));k2=-1.0*(cal(x,sta[mid]));if(k1<k2)r=mid-1;else l=mid+1;}return l-1; } void dfs(ll x,ll pre,ll de,ll top){deep[x]=de;ll k=get(x,top)+1,t1=sta[k],t2=sta[k-1];if(x==1) k=1;ans[x]=-1.0*(cal(t2,x));sta[k]=x;for(ll i=head[x];i;i=nxt[i]){ll y=ver[i];if(y==pre) continue;dfs(y,x,de+1,k);}sta[k]=t1; } int main(){scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&c[i]);//printf("***\n"); }for(ll i=2,a;i<=n;i++){scanf("%lld",&a);add(a,i);}dfs(1,0,1,0);for(ll i=2;i<=n;i++){printf("%lf\n",ans[i]);} } View Code

?

轉載于:https://www.cnblogs.com/znsbc-13/p/11370216.html

總結

以上是生活随笔為你收集整理的NOIP模拟测试24「star way to hevaen·lost my music」的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。