树状数组-高低桥

这个题典型的线段树题,在去年省赛就跪在了上面.那时没想起来用这个.后面回来写过一次但不是很熟练(原谅我写这种题写的少,太依赖模板了= =),再加上昨天早上不知道怎么搞的WA出翔来了...




题目的意思大家大概都看的懂.我就不详细说了,就稍微说下思想吧(没有学霸那么耐心还弄图= =).就先给桥排个序,然后找一下边界,在用树状数组统计一下淹的次数就行了.不是很难,只不过可能理解会难一点.

贴一下代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[111111],b[111111];      
int n,m,k,l,r;

void Bit(int i,int d)         //区间处理
{
    while(i<=n)
    {
        b[i]+=d;
        i+=i&-i;
    }
}

int main()
{
    int tmp,count=1;
    while(cin>>n>>m>>k)
    {
        tmp=0;
        memset(b,0,sizeof(b));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        int pre=0;
        while(m--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            //计算边界
            r=upper_bound(a+1,a+n+1,x)-a;
            l=upper_bound(a+1,a+n+1,pre)-a;
            Bit(l,1);//对区间内的桥淹
            Bit(r,-1);//对多淹的进行回退
            pre=y;
        }
        for(int i=1;i<=n;i++)
        {
             int j=i,sum=0;
             while(j)//累加判断
             {
                  sum+=b[j];
                  j-=j&-j;
             }
            if(sum>=k)
                tmp++;
        }
        cout<<"Case "<<count++<<": ";
        cout<<tmp<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值