2022 ICPC网络预选赛1

本文详细分析了2022年ICPC网络预选赛中涉及的算法问题,包括动态规划、优先队列、递归搜索等策略。通过实例解析A、B、C、D等题目的解题方法,如处理环形后效性、状态压缩和二分查找等技巧,并探讨了赛时思考与抽象能力的重要性。

2022 ICPC网络预选赛1

在这里插入图片描述

A

最难的一点就是没有处理环形后效性

比如询问L=1R=9 ->111000111应该是长度为6的连续一段1,贡献为6/2=3而不是2+2=4

做法就是预处理L右边最近的0的下标x,预处理R左边最近的0的下标y,然后把一段区间分成三份求解,中间就直接贡献sum[y]-sum[x-1]

然后把左边和右边连续的1加起来除于2

做法1,dp处理前缀和贡献

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char s[N];
int n,m,sum[N],L[N],R[N];
int f[N],l,r;
signed main(){
   
   
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m>>s+1;
    int cnt=0;
    for(int i=1;i<=n;i++){
   
   
        if(s[i]=='1')cnt++;
        else cnt=0;
        f[i]=f[i-cnt-1]+(cnt+1)/2;
    }
    L[0]=0;
    for(int i=1;i<=n;i++){
   
   
        if(s[i]=='1')L[i]=L[i-1];
        else L[i]=i;
    }
    R[n+1]=n+1;
    for(int i=n;i>=1;i--){
   
   
        if(s[i]=='1')R[i]=R[i+1];
        else R[i]=i;
    }
    while(m--){
   
   
        cin>>l>>r;
        int len=r-l+1;
        int cnt1=r-L[r]+R[l]-l;
        int t=f[L[r]]-f[R[l]-1]+(cnt1+1)/2;
        cout<<max(0,len/3-t)<<'\n';
    }
}

做法2,对一段连续的1采取贡献差分,也就是+1+0+1+0+1+0,然后前缀和

这样可以保证奇数的时候上取整,偶数下取整

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
char s[N];
int n,m,sum[N],L[N],R[N];
int cal(int l,int r){
   
   
    int ll=R[l];
    int rr=L[r];
    if(ll>=rr)return (r-l+1)/2;
    int len1=(r-rr)+(ll-l);
    return sum[rr]-sum[ll-1]+(len1+1)/2;
}
signed main(){
   
   
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m>>s+1;
    // for(int i=1;i<=n;i++){
   
   
    //     if(s[i]=='1'&&s[i-1]!='1')sum[i]=1;
    //     sum[i]+=sum[i-1];
    // }
    int last=-1;
    for(int i = 1; i <= n ; i ++ ) 
    {
   
   
        if(s[i] == '1')
        {
   
   
            if(last != i - 1) sum[i] = 1, last = i;
            else last = -1;
        }
        sum[i] += sum[i - 1];
    }
    for(int i=1;i<=n;i++){
   
   
        if(s[i]=='0')L[i]=i;
        else L[i]=L[i-1];
    }
    R[n+1]=n+1;
    for(int i=n;i>=1;i--){
   
   
        if(s[i]=='0')R[i]=i;
        else R[i
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值