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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

UR #13 Yist

發布時間:2025/4/9 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UR #13 Yist 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第一次打UR,打了一個半小時就棄療了QAQ

這是我唯一一道考試的時候做出來的題目,其他兩道連暴力都懶得寫了

很容易發現對于每個要刪除的點

我們找到左邊第一個比他小的不用刪除的點,右邊第一個比他小的不用刪除的點

中間這段區間就是對于這個點被刪除時的極大區間

對于所有的區間我們取min就可以了

對于找到某個點左邊第一個比他小的不用刪除的點

我是這樣考慮的:將數從大到小的進行添加,并用并查集維護不用刪除的點

那么之后這個點存在的極大區間顯然是這段區間里的1的個數+1

這個算法是O(na)的

#include<cstdio> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> using namespace std;const int maxn=1000010; int n,T,ans; int a[maxn],pos[maxn]; char b[maxn]; int L[maxn],R[maxn]; int sum[maxn]; int ufsL(int x){return L[x]==x?x:L[x]=ufsL(L[x]);} int ufsR(int x){return R[x]==x?x:R[x]=ufsR(R[x]);} void read(int &num){num=0;char ch=getchar();while(ch<'!')ch=getchar();while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar(); } void Solve(){for(int i=1;i<=n;++i){if(b[i]=='1')sum[i]=sum[i-1]+1;else sum[i]=sum[i-1];}ans=n;L[0]=0;for(int i=1;i<=n;++i){if(b[i]=='1')L[i]=i;else L[i]=ufsL(i-1);}R[n+1]=n+1;for(int i=n;i>=1;--i){if(b[i]=='1')R[i]=i;else R[i]=ufsR(i+1);}for(int i=n;i>=1;--i){int p=pos[i];if(b[p]=='1'){L[p]=ufsL(p-1);R[p]=ufsR(p+1);}else{int A=ufsL(p);int B=ufsR(p);ans=min(ans,sum[B-1]-sum[A]+1);}}return; } int main(){read(n);for(int i=1;i<=n;++i)read(a[i]),pos[a[i]]=i;scanf("%d",&T);while(T--){scanf("%s",b+1);Solve();printf("%d\n",ans);}return 0; }

  

題解給出了一種O(n)的做法,還是回顧剛才的思路

我們注意到我們的并查集只有刪除操作

也就是說如果一個點擴展的時候訪問到之前已經擴展過的點

這個點的區間長度一定比之前擴展的那個點的區間長度要長

由于我們取的是min,所以我們就不用擴展了

這樣我們就可以保證每個元素只訪問一次,每次暴力擴展即可

時間復雜度顯然是O(n)的

轉載于:https://www.cnblogs.com/joyouth/p/5381103.html

總結

以上是生活随笔為你收集整理的UR #13 Yist的全部內容,希望文章能夠幫你解決所遇到的問題。

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