codeforces1167 E. Range Deleting(双指针)
E. Range Deleting
首先不難知道如果f(l,r)f(l,r)f(l,r)滿足題意,那么f(l,r+1),f(l,r+2),…,f(l,x)f(l,r+1),f(l,r+2),\dots,f(l,x)f(l,r+1),f(l,r+2),…,f(l,x)都滿足題意。
因而對(duì)于每一個(gè)左端點(diǎn)lll,需要找到最小的一個(gè)右端點(diǎn)rrr
單調(diào)性:對(duì)于每一個(gè)左端點(diǎn)lll,當(dāng)左端點(diǎn)右移(增大)的過程中,右端點(diǎn)也一定右移(增大)
有了上述單調(diào)性考慮雙指針表示f(i,j)f(i,j)f(i,j)
預(yù)處理出以下數(shù)組
①:l[i]值是i的最小數(shù)組下標(biāo)
②:r[i]值是i的最大數(shù)組下標(biāo)
③:ll[i]值是i~x的最小數(shù)組下標(biāo)
④:rr[i]值是1~i的最大數(shù)組下標(biāo)
對(duì)于一個(gè)區(qū)間[l,r][l,r][l,r],假設(shè)值在[1,l?1][1,l-1][1,l?1]以及[r+1,x][r+1,x][r+1,x]內(nèi)部不存在逆序?qū)?#xff0c;只需要判斷[1,l?1][1,l-1][1,l?1]和[r+1,x][r+1,x][r+1,x]之間是否存在逆序?qū)粗翟?span id="ze8trgl8bvbq" class="katex--inline">[1,l?1][1,l-1][1,l?1]最大數(shù)組下標(biāo)是否大于[r+1,x][r+1,x][r+1,x]最小數(shù)組下標(biāo)即如果存在逆序?qū)?#xff08;rr[l-1]<ll[r+1])不滿足條件,只需根據(jù)此調(diào)整雙指針位置。
對(duì)于假設(shè)條件,顯然可以求出對(duì)于[1,pl)[1,pl)[1,pl)內(nèi)部不存在逆序?qū)?#xff0c;以及(pr,x](pr,x](pr,x]內(nèi)部不存在逆序?qū)?#xff0c;因而只需要讓指針iii在[1,pl][1,pl][1,pl]之間,而指針jjj在[pr,x][pr,x][pr,x]之間即可。
#define IO ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr) #pragma GCC optimize(2) #include<cstring> #include<iostream> #include<algorithm> using namespace std; constexpr int N=1000010; int a[N],n,x; int l[N],r[N],ll[N],rr[N]; int main() {IO;cin>>n>>x;memset(l,0x3f,sizeof l);memset(ll,0x3f,sizeof ll);memset(r,-1,sizeof r);memset(rr,-1,sizeof rr);for(int i=1;i<=n;i++){cin>>a[i];l[a[i]]=min(l[a[i]],i);r[a[i]]=max(r[a[i]],i);}// rr[i] 1~i最右邊的位置// ll[i] i~x最左邊的位置for(int i=1;i<=x;i++) rr[i]=max(rr[i-1],r[i]);for(int i=x;i>=1;i--) ll[i]=min(ll[i+1],l[i]);long long res=0;// [1,pl) 以及 (pr,x] 不存在逆序?qū)?/span>int pl=1,pr=x;while(pl<=x&&rr[pl-1]<=l[pl]) pl++;while(pr>=1&&ll[pr+1]>=r[pr]) pr--; for(int i=1,j=pr;i<=pl;i++){while(j<=x&&(j<i||rr[i-1]>=ll[j+1])) j++;res+=x-j+1;}cout<<res<<'\n';return 0; }要加油哦~
總結(jié)
以上是生活随笔為你收集整理的codeforces1167 E. Range Deleting(双指针)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: codeforces1151 E. Nu
- 下一篇: 宇峻奥汀经典之作《幻世录》被忽略的细节