很容易发现一个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. Docker PHP 例子

    版权所有,未经许可,禁止转载 章节 Docker 介绍 Docker 和虚拟机的区别 Docker 安装 Docker Hub Docker 镜像(image) Docker 容器(container ...

  2. 数据结构必做题参考:实验一T1-20,实验2 T1

    实验一T1-10 #include <bits/stdc++.h> using namespace std; ; struct Book { string isbn; string nam ...

  3. JS location.href传参及接受参数

    当前页面传参 window.location.href= + "&name="+"zhangchenxao"; 下个页面接受参数 var url = l ...

  4. 13 —— node 获取文件属性 —— 加载第三方模块

    以加载第三方时间处理模块( moment )为例 : 一,加载 npm install moment 二,使用介绍 1,点击进入npm官网 https://www.npmjs.com/ 2,搜索 mo ...

  5. sqlserver 联接查询的一些注意点

    1.内连接的安全性 (1) inner join 是ANSI SQL-92 语法.等值联接是ANSI SQL-89 的语法 ,两者已相同方式解释.在性能上没有差别 (2)但是强烈建议使用ANSI SQ ...

  6. comm

    comm [- 123 ] file1 file2 说明:该命令是对两个已经排好序的文件进行比较.其中file1和file2是已排序的文件.comm读取这两个文件,然后生成三列输出:仅在file1中出 ...

  7. c#textBox控件限制只允许输入数字及小数点,是否为空

    c#textBox控件限制只允许输入数字及小数点 转载 //判断按键是不是要输入的类型. if (((int)e.KeyChar < 48 || (int)e.KeyChar > 57) ...

  8. c++的符号表的肤浅认识

    符号表是编译期产生的一个hash列表,随着可执行文件在一起 示例程序 int a = 10; int b; void foo(){ static int c=100; } int main(){ in ...

  9. 一天一个设计模式——工厂方法(FactoryMethod)模式

    一.模式说明 在前一个模板方法(Template Method)模式中,父类定义了处理流程,而流程中用到的方法交给子类去实现.类似的,在工厂方法模式中,父类决定如何生成实例,但并不决定所要生成的具体类 ...

  10. tensorflow中的神经网络笔记

    1.NN----神经网络 2.CNN卷积神经网络 CNN网络一共有5个层级结构: 输入层 卷积层 激活层 池化层 全连接FC层 一.输入层 与传统神经网络/机器学习一样,模型需要输入的进行预处理操作, ...