很容易发现一个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+,M=1e6;
struct fence{int xl,xr,y,i;bool tp;}a[N<<];
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<<];
int n,m,val[N],ans[N];
void pushup(int rt)
{
tr[rt].num=tr[rt<<].num+tr[rt<<|].num;
tr[rt].cut=tr[rt<<].cut|tr[rt<<|].cut;
}
void modify(int rt){tr[rt].cov=,tr[rt].num=;}
void pushdown(int rt){if(tr[rt].cov)modify(rt<<),modify(rt<<|),tr[rt].cov=;}
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>>;
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>>;
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>>,ret=;
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^=;return;}
pushdown(rt);
int mid=l+r>>;
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<<].cut)rt<<=,r=l+r>>;
else rt=rt<<|,l=(l+r>>)+;
return l;
}
return ;
}
int tmp,mid=l+r>>;
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=,x1,y1,x2,y2;i<f;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
a[i<<]=(fence){x1,x2,y1-,i,};
a[i<<|]=(fence){x1,x2,y2,i,};
}
sort(a,a+(f<<));
scanf("%d",&m);
for(int i=;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y);
sort(b+,b+m+);
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d%d",&c[i].x,&c[i].y),c[i].i=i;
sort(c+,c+n+);
f=;
update(M,,M,);
for(int i=M,p=,q=;i;i--)
{
int sum,cut;
while(a[f].y==i)
{
if(!a[f].tp)
{
cover(a[f].xl,a[f].xr,,M,);
if(a[f].xl!=)add(a[f].xl-,-val[a[f].i],,M,);
if(a[f].xl!=)update(a[f].xl-,,M,);
if(a[f].xr!=M)update(a[f].xr,,M,);
}
else{
cut=getnxt(a[f].xr,,M,),sum=query(a[f].xl,a[f].xr,,M,);
val[a[f].i]=query(a[f].xr+,cut,,M,);
cover(a[f].xl,a[f].xr,,M,);
if(a[f].xl>)add(a[f].xl-,sum+val[a[f].i],,M,);
if(a[f].xl!=)update(a[f].xl-,,M,);
if(a[f].xr!=M)update(a[f].xr,,M,);
}
f++;
}
while(b[p].y==i)add(b[p].x,,,M,),++p;
while(c[q].y==i)cut=getnxt(c[q].x,,M,),ans[c[q].i]=query(c[q].x,cut,,M,),++q;
}
for(int i=;i<=n;i++)printf("%d\n",ans[i]);
}

BZOJ4422[Cerc2015]Cow Confinement(扫描线+线段树)的更多相关文章

  1. BZOJ4422 : [Cerc2015]Cow Confinement

    从右往左扫描线,用线段树维护扫描线上每一个点能达到的花的数量,并支持最近篱笆的查询. 对于一朵花,找到它上方最近的篱笆,那么它对这中间的每头牛的贡献都是$1$. 当扫到一个篱笆的右边界时,这中间的答案 ...

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

    4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 61  Solved: 26[Submi ...

  3. HDU 3642 - Get The Treasury - [加强版扫描线+线段树]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

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

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

  5. HDU 3265/POJ 3832 Posters(扫描线+线段树)(2009 Asia Ningbo Regional)

    Description Ted has a new house with a huge window. In this big summer, Ted decides to decorate the ...

  6. 【bzoj4491】我也不知道题目名字是什么 离线扫描线+线段树

    题目描述 给定一个序列A[i],每次询问l,r,求[l,r]内最长子串,使得该子串为不上升子串或不下降子串 输入 第一行n,表示A数组有多少元素接下来一行为n个整数A[i]接下来一个整数Q,表示询问数 ...

  7. hdu1542 Atlantis(扫描线+线段树+离散)矩形相交面积

    题目链接:点击打开链接 题目描写叙述:给定一些矩形,求这些矩形的总面积.假设有重叠.仅仅算一次 解题思路:扫描线+线段树+离散(代码从上往下扫描) 代码: #include<cstdio> ...

  8. P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)

    题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...

  9. Codeforces Gym 101480C - Cow Confinement(扫描线+线段树)

    题面传送门 题意: 有一个 \(10^6\times 10^6\) 的地图.其中 \(m\) 个位置上有花,\(f\) 个矩形外围用栅栏围了起来.保证 \(f\) 个矩形两两之间没有公共点. \(q\ ...

随机推荐

  1. jQuery琐碎

    函数(以click事件为例)在jsp页面和js中的不同写法 onclick="getInfo(this);" function getInfo(obj){ var $this=$( ...

  2. Linux Shell编程case语句

    http://blog.csdn.net/dreamtdp/article/details/8048720 case语句适用于需要进行多重分支的应用情况. case分支语句的格式如下: case $变 ...

  3. JVM探秘:MAT分析内存溢出

    本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. MAT是分析Java堆内存的一个工具,全称是 The Eclipse Memory A ...

  4. Java IO 乱码

    InputStreamReader isr = new InputStreamReader(new FileInputStream("./test/垃圾短信训练集80W条.txt" ...

  5. HDU-4857 逃生(逆向拓扑排序)

    Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. ...

  6. Redis高级用法

    第一章 redis初识 1.1 Redis是什么 介绍 开源:早起版本2w3千行 基于键值对的存储系统:字典形式 多种数据结构:字符串,hash,列表,集合,有序集合 高性能,功能丰富 那些公司在用 ...

  7. PyMySQL学习笔记

    一些常用函数及解释 db = pymysql.connect('host','user','password','database') # 连接数据库 cursor = db.cursor() # 创 ...

  8. Java查漏补缺(3)(面向对象相关)

    Java查漏补缺(3) 继承·抽象类·接口·静态·权限 相关 this与super关键字 this的作用: 调用成员变量(可以用来区分局部变量和成员变量) 调用本类其他成员方法 调用构造方法(需要在方 ...

  9. [APIO2018]铁人两项(圆方树)

    过了14个月再重新看这题,发现圆方树从来就没有写过.然后写了这题发现自己APIO2018打铁的原因竟然是没开long long,将树的部分的O(n)写挂了(爆int),毕竟去年APIO时我啥都不会,连 ...

  10. redis官网下载自动安装脚本

    注释:使用方法为 # ./redis.sh  version           ----version为官网版本号 #!/bin/bashversion=$1serverurl='download. ...