很容易发现一个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. 代理模式(Proxy Pattern)C#版本的

    引用地址 https://www.cnblogs.com/zhili/p/ProxyPattern.html --------------------------------------------- ...

  2. Win7微信DLL劫持反弹SHELL(10.9 第十七天)

    (该文参考自网络其他人资料,仅为学习,不得用于非法用途) 准备的工具:kali虚拟机 W7虚拟机 微信 ProcessExplorer the-backdoor-factory-master 打开微信 ...

  3. 关于数据库text字段

    问题描述: maven项目中,使用MBG代码生成器自动生成的实体类对象时,当数据库中表的字段有 text 类型时,对应到java类中是String类型的,在前端页面通过ajax获取到 json 格式的 ...

  4. POJ 2586:Y2K Accounting Bug

    Y2K Accounting Bug Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11297   Accepted: 56 ...

  5. java课程课后作业190502之单词统计续集

    第1步:输出单个文件中的前 N 个最常出现的英语单词. 功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列. 功能2: 指定文件目录,对目录下每一个文件执行统 ...

  6. C语言:大数求和

    点击获取题目 1410: [蓝桥杯]高精度加法 时间限制: 1 Sec  内存限制: 256 MB提交: 28  解决: 20[状态] [提交] [命题人:外部导入] 题目描述 输入两个整数a和b,输 ...

  7. UVA 11235 RMQ算法

    上次的湘潭赛的C题,用线段树敲了下还是WA,不知道为何,我已经注意了处理相同数据,然后他们当时用的RMQ. 所以学了下RMQ,感觉算法思想是一样的,RMQ用了DP或者是递推,由单个数到2^k往上推,虽 ...

  8. Mybatis实现条件查询(三)

    1. 准备 请先完成Mybatis基本配置(一)的基本内容 2. 疑问 我们再Mybatis基本配置(一)中实现了按照商品ID进行查询商品信息,可是在实际应用中却很少出现根据ID来查询商品的情况.因为 ...

  9. 题解 Luogu P2499: [SDOI2012]象棋

    关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可 ...

  10. mysql字符类型总结及常用字符函数

    常用字符串函数: concat(s1,s2,s3..)       连接s1,s2,...sn为一个字符串 INSERT(str,x,y,instr)将字符串str从x位置开始,y个字符串替换为字符串 ...