codeforces 338e

5 篇文章 0 订阅
3 篇文章 0 订阅

题意:根据伪代码 求出答案

思路:其实他要我们求的是一个符合他条件 a[] 的连续的子串有多少个 这个字串必须满足一个条件 就是经过和b[]任意的匹配后 每一对数之和需要大于等于 一个特定的值  那么 最优的方案就是贪心  子串最大的 和  最小的b[]的匹配 第二大和第二小的 。。。。 如此匹配 虽然源代码得到的最后匹配不是这个 但是如果不满足这个方案 就肯定无解

对于每个a[] 我们可以从b[]中知道在他可以匹配的最小b[]是多少 记位置为x 那么b[]  x 到 m 小的值都可以匹配 于是用线段树来进行区间更新


ps:想到用区间更新了 但是以为自己想的那样会超时  结果就没写出来  看来别人代码才知道  底子不扎实 自己骗自己 


#include<cstring>
#include<cstdlib>
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define N 150010
#define MOD 1000000009
#define LL long long

int a[N];
int b[N];
int c[N*4];
int p[N*4];
int q[N*4];

int n,m,k;

void update(int tt)
{
    c[tt*2]+=p[tt];c[tt*2+1]+=p[tt];
    p[tt*2]+=p[tt];p[tt*2+1]+=p[tt];
    p[tt]=0;
}

void change(int l,int r,int tt,int x,int y,int k)
{
    if(l==x&&r==y)
    {
        c[tt]+=k;
        p[tt]+=k;
        return ;
    }
    update(tt);
    int mid=(l+r)/2;
    if(x>mid)change(mid+1,r,tt*2+1,x,y,k);
    else if(y<=mid)change(l,mid,tt*2,x,y,k);
    else
    {
        change(mid+1,r,tt*2+1,mid+1,y,k);
        change(l,mid,tt*2,x,mid,k);
    }
    c[tt]=min(c[tt*2],c[tt*2+1]);
}

int fd(int x)
{
    int l=1,r=m,ret=m+1;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(x+a[mid]>=k)
        {
            ret=mid;
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    return ret;
}

int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a+1,a+m+1);
    for(int i=1;i<=m;i++) change(1,m,1,i,i,-i);
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
        q[i]=fd(b[i]);
        if(q[i]<=m)change(1,m,1,q[i],m,1);
        if(i>m&&q[i-m]<=m)change(1,m,1,q[i-m],m,-1);
        ans+=c[1]>=0;
    }
    printf("%d\n",ans);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值