zoukankan      html  css  js  c++  java
  • 线段树 乌鸦喝水

    问题 B: 乌鸦喝水
    时间限制: 2 Sec 内存限制: 128 MB
    题目描述
    【题目背景】
    一只乌鸦在自娱自乐,它在面前放了n个有魔力的水缸,水缸里装有无限的水。
    【题目描述】
    他准备从第1个水缸飞到第n个水缸,共m次。在飞过一个水缸的过程中,如果他能够得着水缸里的水,即水缸口到水面距离小于等于乌鸦能够得着的深度,那它就会喝水缸里的水。每喝一次水,所有水缸里的水位都会下降,第i个水缸里的水位会下降Ai,注意喝水是瞬间的,如果乌鸦刚好够得着,但喝完之后够不着,也视为喝到一次,水位也会相应的下降。
    Input
    共有3行。第一行有三个正整数n、m和x,用空格隔开。n表示水缸的数量,m表示乌鸦飞的次数,x表示乌鸦能够得着的深度。第二行,有n个用空格隔开的正整数,第i个数为第i个水缸中水缸口到水面的距离Wi。第三行,有n个用空格隔开的正整数,第i个为Ai。
    Output
    只有一行,这一行只有一个正整数,为这只乌鸦能喝到水的次数。
    Sample Input
    5 2 20
    15 14 13 12 12
    1 1 1 1 1
    Sample Output
    9
    【数据范围】
    100%的数据,0<n≤100000,0<m≤100000,0<x≤2000000000,0<Wi≤2000000000,0<Ai≤200。

    设 num=(X-w[i])/a[i]这个就是当前的缸还能撑住水位下降几次。
    又因为虽然他能撑住这么多次,但是乌鸦飞到他上面前还要过i-1个缸,又要喝水。
    所以num[i]=(X-w[i])/a[i]-i+1;这样就可以了。但是如果前面的一个缸不会被喝水,那么后面就被多减了,其实可以找到第一个会被干掉的点,删掉,再给他后面的区间+1,就又解决了。耳罩第一个不符合的点只要维护个区间最小,二分一下。
    所以每一轮只要删掉所有不满足的,给后面加回来,让ans+=根节点上符合的个数就好了。
    跑得贼快。

    #pragma GCC optimize("O3")
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 100005
    #define mod 10000000007ll
    #define ll long long
    using namespace std;
    struct tree{int l,r;ll h,lz,sum;}t[N*4];
    int n,m;ll ans,X,w[N],a[N],zz[N];
    ll min(ll x,ll y){return x<y?x:y;}
    void down(int x)
    {
        ll l=t[x].lz;t[x].lz=0;
        t[x*2].h+=l;t[x*2].lz+=l;
        t[x*2+1].h+=l;t[x*2+1].lz+=l;
    }
    void build(int l,int r,int x)
    {
        t[x].l=l;t[x].r=r;
        if(l==r)
        {
            t[x].h=(X-w[l])/a[l]-l+1;
            t[x].sum=1;
            return;
        }
        int mid=l+r>>1;
        build(l,mid,x*2);build(mid+1,r,x*2+1);
        t[x].sum=t[x*2].sum+t[x*2+1].sum;
        t[x].h=min(t[x*2].h,t[x*2+1].h);
    }
    void c(int l,int r,int x)
    {
        if(l>r)return ;
        if(t[x].l>=l&&t[x].r<=r)
        {
            t[x].h++;t[x].lz++;
            return;
        }
        if(t[x].lz)down(x);
        int mid=t[x].l+t[x].r>>1;
        if(l<=mid)c(l,r,x*2);
        if(r>mid)c(l,r,x*2+1);
        t[x].sum=t[x*2].sum+t[x*2+1].sum;
        t[x].h=min(t[x*2].h,t[x*2+1].h);
    }
    void del(int l,int x)
    {
        if(t[x].l==t[x].r)
        {
            t[x].h=mod;t[x].sum=0;
            return;
        }
        int mid=t[x].l+t[x].r>>1;
        if(t[x].lz)down(x);
        if(l<=mid)del(l,x*2);
        else del(l,x*2+1);
        t[x].sum=t[x*2].sum+t[x*2+1].sum;
        t[x].h=min(t[x*2].h,t[x*2+1].h);
    }
    int q(ll k,int x)
    {
        if(t[x].l==t[x].r)return t[x].l;
        if(t[x].lz)down(x);
        if(t[x*2].h<k)return q(k,x*2);
        else return q(k,x*2+1);
    }
    int main()
    {
        //freopen("hh.txt","r",stdin);
    //  freopen(".out","w",stdout);
        scanf("%d%d%lld",&n,&m,&X);
        for(int i=1;i<=n;i++)scanf("%lld",&w[i]);
        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
        build(1,n,1);
        while(m--)
        {
            while(t[1].h<ans)
            {
                //cout<<t[1].h<<endl;
                int k=q(ans,1);
                del(k,1);c(k+1,n,1);
            }
            ans+=t[1].sum;
            if(!t[1].sum)break;
        }
        printf("%lld
    ",ans);
    }
  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7674425.html
Copyright © 2011-2022 走看看