Collecting Numbers II

纯粹的發表於2024-07-31

原題連結

題解

如果一個 \(k\) ,其前面沒有出現過 \(k-1\) ,那麼回合數+1,我們令這樣的數叫做斷點

因此交換兩個數 \(l,r\) 不會影響 \([1,l-1],[r+1,n]\) 內的斷點

code

#include<bits/stdc++.h>
#define ll long long
#define lowbit(x) ((x)&(-x))
using namespace std;
const ll inf=1e18;
const ll mod=1e9+7;

ll a[200005];
ll pos[200005];

void solve()
{
    ll n,m;
    cin>>n>>m;

    for(ll i=1;i<=n;i++)
    {
        ll x;
        cin>>x;
        pos[x]=i;
        a[i]=x;
    }

    ll ans=1;
    for(ll i=2;i<=n;i++) ans+=pos[i-1]>pos[i];

    while(m--)
    {
        ll x,y;
        cin>>x>>y;
        if(x>y) swap(x,y);
        ll vx=a[x],vy=a[y];
        if(vx>1&&pos[vx-1]>x&&pos[vx-1]<y) ans--;
        if(vx<n&&pos[vx+1]>x&&pos[vx+1]<y) ans++;
        if(vy>1&&pos[vy-1]>x&&pos[vy-1]<y) ans++;
        if(vy<n&&pos[vy+1]>x&&pos[vy+1]<y) ans--;
        if(abs(vx-vy)==1)
        {
            if(vx>vy) ans--;
            else ans++;
        }
        swap(a[x],a[y]);
        swap(pos[vx],pos[vy]);

        cout<<ans<<'\n';
    }
}
int main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int TT=1;
    //cin>>TT;
    while(TT--) solve();
    return 0;
}

相關文章