• BZOJ4422[Cerc2015]Cow Confinement(扫描线+线段树)


    很容易发现一个O(n2)DP,f[i][j]=f[i][j+1]+f[i+1][j]-f[i+1][j+1]。然后由于有栅栏,一些位置没办法走,然后就可以用类似差分的方法,f[i]表示当前行f[i+1]无法到达的花朵,然后对于每个点找到其下方第一个栅栏。分情况讨论,需要支持单点修改(出现花),区间标记覆盖(出现一个栅栏),以及区间归零(栅栏走了),当然还要区间查询(牛出现了),然后还要支持第一个障碍物的查询,不过这些用一个操作较多的线段树就可以跑过了,复杂度一个log可以“轻松”跑过。

    #include<cstdio>
    #include<algorithm>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    using namespace std;
    const int N=2e6+7,M=1e6;
    struct fence{int xl,xr,y,i;bool tp;}a[N<<1];
    bool operator<(fence a,fence b){return a.y!=b.y?a.y>b.y:a.xl<b.xl;}
    struct flower{int x,y;}b[N];
    bool operator<(flower a,flower b){return a.y>b.y;}
    struct cow{int x,y,i;}c[N];
    bool operator<(cow a,cow b){return a.y>b.y;}
    struct seg{int num;bool cov,cut;}tr[N<<2];
    int n,m,val[N],ans[N];
    void pushup(int rt)
    {
        tr[rt].num=tr[rt<<1].num+tr[rt<<1|1].num;
        tr[rt].cut=tr[rt<<1].cut|tr[rt<<1|1].cut;
    }
    void modify(int rt){tr[rt].cov=1,tr[rt].num=0;}
    void pushdown(int rt){if(tr[rt].cov)modify(rt<<1),modify(rt<<1|1),tr[rt].cov=0;}
    void add(int k,int v,int l,int r,int rt)
    {
        tr[rt].num+=v;
        if(l==r)return;
        pushdown(rt);
        int mid=l+r>>1;
        if(k<=mid)add(k,v,lson);else add(k,v,rson);
        pushup(rt);
    }
    void cover(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R){modify(rt);return;}
        pushdown(rt);
        int mid=l+r>>1;
        if(L<=mid)cover(L,R,lson);
        if(R>mid)cover(L,R,rson);
        pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)return tr[rt].num;
        pushdown(rt);
        int mid=l+r>>1,ret=0;
        if(L<=mid)ret+=query(L,R,lson);
        if(R>mid)ret+=query(L,R,rson);
        return ret;
    }
    void update(int k,int l,int r,int rt)
    {
        if(l==r){tr[rt].cut^=1;return;}
        pushdown(rt);
        int mid=l+r>>1;
        if(k<=mid)update(k,lson);else update(k,rson);
        pushup(rt);
    }
    int getnxt(int L,int l,int r,int rt)
    {
        if(l>=L)
        {
            if(tr[rt].cut)
            {
                while(l!=r)
                if(tr[rt<<1].cut)rt<<=1,r=l+r>>1;
                else rt=rt<<1|1,l=(l+r>>1)+1;
                return l;
            }
            return 0;
        }
        int tmp,mid=l+r>>1;
        pushdown(rt);
        if(L<=mid&&(tmp=getnxt(L,lson)))return tmp;
        return getnxt(L,rson);
    }
    int main()
    {
        int f;scanf("%d",&f);
        for(int i=0,x1,y1,x2,y2;i<f;i++)
        {
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            a[i<<1]=(fence){x1,x2,y1-1,i,0};
            a[i<<1|1]=(fence){x1,x2,y2,i,1};
        }
        sort(a,a+(f<<1));
        scanf("%d",&m);
        for(int i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y);
        sort(b+1,b+m+1);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d%d",&c[i].x,&c[i].y),c[i].i=i;
        sort(c+1,c+n+1);
        f=0;
        update(M,1,M,1);
        for(int i=M,p=1,q=1;i;i--)
        {
            int sum,cut;
            while(a[f].y==i)
            {
                if(!a[f].tp)
                {
                    cover(a[f].xl,a[f].xr,1,M,1);
                    if(a[f].xl!=1)add(a[f].xl-1,-val[a[f].i],1,M,1);
                    if(a[f].xl!=1)update(a[f].xl-1,1,M,1);
                    if(a[f].xr!=M)update(a[f].xr,1,M,1);
                }
                else{
                    cut=getnxt(a[f].xr,1,M,1),sum=query(a[f].xl,a[f].xr,1,M,1);
                    val[a[f].i]=query(a[f].xr+1,cut,1,M,1);
                    cover(a[f].xl,a[f].xr,1,M,1);
                    if(a[f].xl>1)add(a[f].xl-1,sum+val[a[f].i],1,M,1);
                    if(a[f].xl!=1)update(a[f].xl-1,1,M,1);
                    if(a[f].xr!=M)update(a[f].xr,1,M,1);
                }
                f++;
            }
            while(b[p].y==i)add(b[p].x,1,1,M,1),++p;
            while(c[q].y==i)cut=getnxt(c[q].x,1,M,1),ans[c[q].i]=query(c[q].x,cut,1,M,1),++q;
        }
        for(int i=1;i<=n;i++)printf("%d
    ",ans[i]);
    }
    View Code
  • 相关阅读:
    懒加载
    通过Xib自定义控件
    自定义控件
    swiper_banner图的封装
    uni-app中封装的search和scroll-view
    使用git从创建仓库或项目到push到远程并创建分支常用命令
    随手封装一个简单的日期组件(基于ele-ui的基础上)
    封装的一个时间条插件
    websocket的封装2
    websocket的封装1(做vue中的通信经常也是大概率用到的)
  • 原文地址:https://www.cnblogs.com/hfctf0210/p/10953145.html
Copyright © 2020-2023  润新知