• cf 338E


    题目大意

    有长度为 m 的序列 b 和长度为 n 的序列 a,问序列 a 中有多少个长度为 m 的区间能和序列 b 匹配。两个序列中的元素 x; y 能配对当且仅当 x + y ≥ h,两个序列能匹配当且仅当存在完备匹配。 

    题解

    非常简单的线段树题。做变换b[i]=h-b[i],再排个序,就转换成了这样的问题,每次考虑a中连续的m个数,要求这些数中比b数组中第i个数b[i]大的有至少m-i+1个。这个线段树维护一下就可以了。

    #include <bits/stdc++.h>
    #define ll long long
    #define inf 0x6fffffff
    #define N 150086
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,h,ans;
    int a[N],b[N];
    map<int,int>mp;
    int cnt,tt;
    int f[N*4],tag[N*4];
    int tmp[2*N];
    void build(int i,int l,int r,int ps,int dd)
    {
        if(l==r){f[i]=-dd;return; }
        int mid=(l+r)/2;
        if(ps<=mid)build(i*2,l,mid,ps,dd);
            else build(i*2+1,mid+1,r,ps,dd);
        f[i]=min(f[i*2],f[i*2+1]);
    }
    void ins(int i,int l,int r,int lt,int rt,int dd)
    {
        if(lt<=l&&r<=rt){tag[i]+=dd;f[i]+=dd;return;}
        int mid=(l+r)/2;
        if(lt<=mid)ins(i*2,l,mid,lt,rt,dd);
        if(mid+1<=rt)ins(i*2+1,mid+1,r,lt,rt,dd);
        f[i]=min(f[i*2],f[i*2+1])+tag[i];
    }
    int main()
    {
        int n=read(),m=read(),h=read();
        for(int i=1;i<=m;i++)b[i]=h-read(); 
        for(int i=1;i<=n;i++)a[i]=read();
        for(int i=1;i<=n;i++)tmp[++tt]=a[i];
        for(int i=1;i<=m;i++)tmp[++tt]=b[i];
        sort(tmp+1,tmp+tt+1);sort(b+1,b+m+1);
        for(int i=1;i<=tt;i++)if(mp[tmp[i]]==0)mp[tmp[i]]=++cnt;
        for(int i=1;i<=n;i++)a[i]=mp[a[i]];
        for(int i=1;i<=m;i++)b[i]=mp[b[i]];
        //for(int i=1;i<=n;i++)printf("%d%c",a[i],(i!=n)?' ':'
    ');
        //for(int i=1;i<=m;i++)printf("%d%c",b[i],(i!=m)?' ':'
    ');
        for(int i=1;i<=m;i++)build(1,1,cnt,b[i],m-i+1);
        for(int i=1;i<=m;i++)ins(1,1,cnt,1,a[i],1);
        if(f[1]>=0)ans=1;else ans=0;
        for(int i=m+1;i<=n;i++)
        {
            ins(1,1,cnt,1,a[i],1);
            ins(1,1,cnt,1,a[i-m],-1);
            if(f[1]>=0)ans++;
        }
        cout<<ans<<endl;
        //system("pause");
        return 0;
    }
    View Code
  • 相关阅读:
    C语言学习第八章
    C语言学习第七章
    C语言学习第六章
    C语言学习第五章
    ssh的bug
    Oracel 用户管理
    初识Kettle
    IDEA使用MAVEN时自动创建骨架卡的设置
    2017/6/12 JSON
    DDL,DML,DQL
  • 原文地址:https://www.cnblogs.com/oldjang/p/10524844.html
Copyright © 2020-2023  润新知