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

歡迎訪問 默认站点!

默认站点

當前位置: 首頁 >

NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」...

發(fā)布時間:2023/12/2 37 豆豆
默认站点 收集整理的這篇文章主要介紹了 NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目比較神仙,注意是題目神仙

貪婪暗示貪心,堆積暗示堆優(yōu)化$\%\%\%\%\%\%\%$

兩個亂搞$+$一個堆優(yōu)化$dp$

嚎叫響徹在貪婪的機房

題解

對于一個序列來說只要他們差的$gcd$不為$1$就可以構(gòu)成等差數(shù)列

例如

$2$ ?? $4$ ??? $16$

$2$與$4$差$2$ $4$與$16$差$12$?

$gcd(2,12)!=1$故構(gòu)成等差序列

那么我們維護公差,然后每次的差和當前公差比較,若$gcd==1$則等差數(shù)列從這里斷開,否則將公差置成$gcd$

舉個例子

$2$ ??? $8$ ?? $14$ ???? $16$ ??? $18$ ???? $20$

$2$ ??? $8$ ?? $14$構(gòu)成公差為$6$等差數(shù)列,之后$16$ ??? $18$ ???? $20$構(gòu)成公差為$2$等差序列

顯然我們可以讓他們合并為公差為$2$等差序列

注意判重,判差為$1$,

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1111111 ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f; } set<ll> st; set<ll> ::iterator it; ll n,m,d=0,ans=0; ll a[A]; void cl(ll x){st.clear();d=0;ans++;st.insert(a[x]); } ll gcd(ll x,ll y){if(y==0) return x;return gcd(y,x%y); } int main(){n=read();for(ll i=1;i<=n;i++){a[i]=read();}cl(1);for(ll i=2;i<=n;i++){if((it=st.find(a[i]))!=st.end()) { // printf("i=-%lld\n",i); cl(i);continue;}if(abs(a[i]-a[i-1])==1||a[i]==a[i-1]){cl(i);continue;} // printf("d=%lld\n",d);if(d==0){st.insert(a[i]);d=abs(a[i]-a[i-1]);}else {ll g=gcd(d,abs(a[i]-a[i-1])); // printf("g=%lld d=%lld abs=%lld\n",g,d,abs(a[i]-a[i-1]));if(g==1||g==0){cl(i);}else {st.insert(a[i]);d=g;}}}printf("%lld\n",ans); } View Code

主仆見證了 Hobo 的離別

題解

建邊,建立包含關(guān)系的樹,例如$1,2$交集為$3$那么$1$包含$3$,$2$包含$3$

再例如$1,2$并集為$3$那么$3$包含$1$,$3$包含$2$

詢問$x$,$y$所屬關(guān)系就從$y$開始$dfs$若找到$x$即符合

暴力就是正解

讓我們分析一下復雜度

題目中說

新元件的編號等于融合之前元件的總個數(shù)加一。當然,參與融合的 K個元件融合之后依然存在,并且每個元件至多參與一次融合

數(shù)據(jù)范圍

?

極限情況下肯定就是分開連邊

那么$250000$個分開連邊,產(chǎn)生$125000$,然后下一層產(chǎn)生$62500$再下一層.....

顯然是$log$的最終是$18$層

而且我們建出來樹是下圖這樣的從一點往下搜

?

所以極限復雜度$18*250000$可過

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1111111 ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f; } ll n,m,cnt,ok,tot=0; ll some[A],fa[A],nxt[A],ver[A],head[A]; ll find(ll x){if(fa[x]!=x){fa[x]=find(fa[x]);}return fa[x]; } void haha(){for(ll i=1;i<=500000;i++){fa[i]=i;} } void merge(ll x,ll y){x=find(x),y=find(y);if(x!=y) fa[x]=y; } void add(ll x,ll y){ // printf("x=%lld y=%lld\n",x,y);nxt[++tot]=head[x],head[x]=tot,ver[tot]=y; } void dfs(ll x,ll pre,ll ineed){if(x==ineed) ok=1;if(ok) return ;for(ll i=head[x];i;i=nxt[i]){ll y=ver[i];if(y==pre) continue;dfs(y,x,ineed);} } /*ll ithave[A],beihave[A]; ll getithave(ll x){if(ithave[x]!=x){ithave[x]=getithave(ithave[x]);}return ithave[x]; } void mergeit(ll x,ll y){x=getithave(x);y=getithave(y);if(ithave[x]!=ithave[y]){ithave[x]=y;} } ll getbeihave(ll x){if(beihave[x]!=x){beihave[x]=getbeihave(beihave[x]);}return beihave[x]; } void mergebei(ll x,ll y){x=getbeihave(x);y=getbeihave(y);if(beihave[x]!=beihave[y]){beihave[x]=y;} }*/ int main(){n=read(),m=read();cnt=n;for(ll i=1,opt,ques,k,QwQ;i<=m;i++){ques=read();if(ques==0){opt=read(),k=read();cnt++;if(opt==1){for(ll j=1;j<=k;j++){QwQ=read();//1屬于2 1--->2 add(cnt,QwQ);if(k==1)add(QwQ,cnt);}}else {for(ll j=1;j<=k;j++){QwQ=read();add(QwQ,cnt);if(k==1)add(cnt,QwQ);}}}else{ok=0;ques=read(),QwQ=read();dfs(QwQ,0,ques);printf("%lld\n",ok);}} } View Code

征途堆積出友情的永恒

題解

?首先普通dp應該都會吧

$f[i]=min(f[j]+max(sum[i]-sum[j],b[j]))$

for(ll i=1;i<=n;i++){for(ll j=max(i-k,0ll);j<=i-1;j++){ll fee=max(sum[i]-sum[j],a[j]);f[i]=min(f[j]+fee,f[i]);}} 一言不和上代碼

怎么優(yōu)化,

線段樹或者堆

思考sum[i]變化很煩,線段樹很難維護(然而Mr_zkt維護出來了$%%%$)我沒打線段樹

用堆維護我們需要尋找不變量顯然$f[j]+b[j]$和$f[j]-sum[j]$是不變量

開兩個小根堆,一個維護$min(f[j]+b[j])$一個維護$f[j]-sum[j]$

轉(zhuǎn)移時$min(q1.top(),q2.top+sum[i])$

細節(jié)稍多

  • $STL$的各種$empty$往上仍,
  • 判斷是否可以轉(zhuǎn)移(<=k)限制
  • 在$f[j]+b[j]$$<$$f[j]-sum[j]+sum[i]$時第一個堆不合法,第一個堆扔到第二個堆

代碼

#include<bits/stdc++.h> using namespace std; #define ll long long #define A 1010101 ll f[A],a[A],sum[A],b[A]; ll n,k,minn; struct node{ll id,val;friend bool operator < (const node &a,const node &b){return a.val>b.val;} }; priority_queue<node> q1,q2; //q1用來存f+b q2存 f-s ll read(){ll x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+(c-'0');c=getchar();}return f*x; } void work(){memset(f,0x3f,sizeof(f));f[0]=0;node o;o.id=0,o.val=b[0];q1.push(o);for(ll i=1;i<=n;i++){node x1,x2;while(!q1.empty()){x1=q1.top();if(x1.id>=i-k) break;q1.pop();}while(!q2.empty()){x2=q2.top();if(x2.id>=i-k) break;q2.pop();}while(!q1.empty()){x1=q1.top();if(x1.val>=f[x1.id]-sum[x1.id]+sum[i]) break; // printf("feifa\n"); // printf("x1.val=%lld id=%lld f-s=%lld\n",x1.val,x1.id,f[x1.id]-sum[x1.id]+sum[i]); q1.pop();node x3;x3.id=x1.id,x3.val=f[x1.id]-sum[x1.id];q2.push(x3);}while(!q1.empty()){x1=q1.top();if(x1.id>=i-k) break;q1.pop();}while(!q2.empty()){x2=q2.top();if(x2.id>=i-k) break;q2.pop();} // printf("q1.top id=%lld val=%lld 2=%lld %lld\n",x1.id,x1.val,x2.id,x2.val);//f[i]=min(x1.val,x2.val+sum[i]);if(!q1.empty())f[i]=min(0x7ffffffffff,q1.top().val);if(!q2.empty())f[i]=min(0x7ffffffffff,q2.top().val+sum[i]); // printf("f[%lld]=%lld\n",i,f[i]);x1.id=i,x1.val=f[i]+b[i];q1.push(x1);} } int main(){n=read(),k=read();for(ll i=1;i<=n;i++){sum[i]=read();sum[i]+=sum[i-1];}for(ll i=0;i<n;i++){b[i]=read();}work();printf("%lld\n",f[n]); } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/znsbc-13/p/11377871.html

總結(jié)

以上是默认站点為你收集整理的NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得默认站点網(wǎng)站內(nèi)容還不錯,歡迎將默认站点推薦給好友。