很容易发现一个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\n",ans[i]);
}

View Code

转载于:https://www.cnblogs.com/hfctf0210/p/10953145.html

BZOJ4422[Cerc2015]Cow Confinement(扫描线+线段树)相关推荐

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

    === === 这里放传送门 === === 题解 记得这题很久以前学长出过胡策..然后当时没做出来..然后照着题解打了一发然后怎么调怎么WA然后就弃了..当时的题解好像是用差分什么的?基本思路是对每 ...

  2. 【BZOJ-4422】Cow Confinement 线段树 + 扫描线 + 差分 (优化DP)

    4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec  Memory Limit: 512 MB Submit: 61  Solved: 26 [Sub ...

  3. Bzoj 4422: [Cerc2015]Cow Confinement(线段树+扫描线)

    以下内容来自ShallWe's Blog 题目 题目链接 4422: [Cerc2015]Cow Confinement Description 一个10^6行10^6列的网格图,上面有一些牛.花和一 ...

  4. 【HDU5091】Beam Cannon,扫描线+线段树

    传送门 思路: 扫描线的经典问题 然而并不是很会做-- 对x坐标差分一下(例如(x,y)类型为1,(x+w,y)的类型就是-1,以便于之后扫描可以去除该点),然后对y坐标转化为正数(便于操作为线段树上 ...

  5. 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树

    [BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...

  6. 扫描线+线段树简介 AcWing 248窗内的星星题解

    ----出自南昌理工学院ACM集训队 这周学习了线段树和扫描线的解题方法,下面由小菜鸡简介一下: 一般扫描线的题目最简单的便是扫描线裸模板(一般来说的话:数据范围小),其次的话便是进行拓展成线段树+扫 ...

  7. 【BZOJ4422】Cow Confinement【扫描线】【差分】【线段树】

    题意 一个10610^6106行10610^6106列的网格图,上面有一些牛.花和一些矩形围栏,围栏在格子的边界上,牛和花在格子里,牛只能向下或向右走,不能穿过围栏和地图边界,求每头牛它能到达的花的数 ...

  8. POJ 1177 Picture [离散化+扫描线+线段树]

    http://poj.org/problem?id=1177 给若干矩形,求被覆盖的区域的周长. 将 y 坐标离散化后,按 x 坐标进行扫描.用线段树维护两个东西,当前竖线的叠加长度 len 和 条数 ...

  9. hdu 4419 Colourful Rectangle (离散化扫描线线段树)

    Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...

最新文章

  1. Docker安全性支持(使用Cgroups机制实现容器资源控制)
  2. 机器人驾驶的神经网络愿景(下)
  3. 三星Galaxy Note20系列价格曝光:大小杯差距明显
  4. security面试_41 道 Spring Boot 面试题,帮你整理好了!
  5. visual studio 2008 intellisense does not work
  6. WCF分布式开发常见错误(17):无法启动MSMQ服务
  7. java 密码复杂度_java密码复杂度校验
  8. DVB 数字电视基础知识
  9. 物联网平台建设调研报告
  10. ICASPP2022论文阅读记录2 - Transformer-S2A
  11. 汾阳哪里有计算机培训班,汾阳市2020年第六期 吕梁山护工培训班开班
  12. (原创)ics-openvpn编译详解
  13. 从数字城市迈向智能城市
  14. 什么是数据分析报告,主要有什么价值?
  15. python3进阶之正则表达式之re模块之分组(group)、贪心匹配、编译
  16. tail命令 – 查看文件尾部内容
  17. 计算机考研2018大纲,2018计算机考研大纲(word版)
  18. java pass can not be_java – 校验和失败:Kerberos / Spring / Active Directory(2008)
  19. 涂鸦智能股权曝光:王学集持股19.9% 公司市值蒸发超百亿美元
  20. 打造一个属于自己的ip代理工具 ProxyRoot

热门文章

  1. 命令行批量合并视频脚本
  2. 保险业务与系统——LOMA 290 保险公司运营——第三讲——寿险公司的组建和重组
  3. MIFARE 处理 7字节UID卡片
  4. HistCite的Format: Unknown问题如何解决
  5. 计算机各科最高成绩查询用啥公式,计算机和数学公式.doc
  6. Mac 下使用 VS Code 生成 C++ 的 Google Protocal Buffer 项目及使用记录
  7. Linux学习之一键建站脚本
  8. C++的头文件,源文件区别
  9. word中让页面变大
  10. 生物信息学练习题-三阳