1849C-Binary String Copying

题目链接:Binary String Copying

首先给出一串字符串观察一下:

001010111

假设当L=2,R=7时 那么最后排序的情况是:000011111

假设当L=1,R=8时 可以发现最后的排序情况跟上面一种情况是一样的

更直观点来看:

000000011111111

当L处于左边0的任何位置,R处于右边1的任何位置,那么最终的结果不会发生变化

因此可以记录一下每个0右边第一个1的位置,同时记录每个1左边第一个0的位置,那么只需修改中间值即可。如图:

 

对于左边任何区间来说,不管L在哪最后结果都是一样,修改的是红色区间,右边也一样。

最后用map哈希表记录即可。

代码附上:

#include <bits/stdc++.h>
#define int long long
#define first x
#define second y
using namespace std;
const int N =2e5+5;
int l[N],r[N];
int n,m;
int a[N];

void solve(){
    map<pair<int,int>,int>mp;
    cin>>n>>m;
    string s;cin>>s;
    for(int i=1;i<=n;i++){
        a[i]=s[i-1]-'0';
    }

    int pos=0;
    for(int i=1;i<=n;i++){//每个1左边第一个0的位置
        if(a[i]==0)pos=i;
        l[i]=pos;
    }

    pos=n+1;
    for(int i=n;i>=1;i--){//每个0右边第一个1的位置
        if(a[i]==1)pos=i;
        r[i]=pos;
    }
    int ans=0;
    for(int i=1;i<=m;i++){
        int x,y;cin>>x>>y;
        x=r[x];
        y=l[y];
        if(x>y)x=1,y=1;//跟原来字符串一样,不变
        if(!mp[{x,y}]){
            mp[{x,y}]=1;
            ans++;
        }
    }
    cout<<ans<<"\n";
    return;
}

signed main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
    while(t--){
        solve();
    }

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值