BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=4422
我真服了。。这题我能调一天半,最后还是对拍拍出来的。。。脑子还是有病啊
题解: 首先可以dp, 分情况讨论: 若下面右面都有栅栏则值为零,若仅下面有栅栏则dp值等于右面,若仅右面有栅栏则dp值等于下面,若\((i,j)\)满足存在一矩形\((i+1,j+1)-(x,y)\)则dp[i][j]=dp[i+1][j]+dp[i][j+1]-dp[x+1][y+1],否则dp[i][j]=dp[i+1][j]+dp[i][j+1]-dp[i+1][j+1]
然后考虑用线段树+扫描线优化。差分之后推一波发现只需要支持: 单点加、区间覆盖(为0)、区间求和。
扫描线写得还是不熟。注意如果从右往左扫,同一竖列一定要先加入栅栏再删除栅栏!如数据:
5
2 6 6 7
1 9 9 9
8 4 9 5
2 1 3 3
10 2 10 2
10
4 5
10 4
8 10
4 3
1 10
10 3
9 4
8 10
6 6
5 10
1
1 3
代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<set>
#include<iostream>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+(c^'0');
if(f) return x;
return -x;
}
const int N = 2e5;
const int C = 1e6;
struct SegmentTree
{
struct SgTNode
{
int sum,tag;
SgTNode() {sum = 0,tag = -1;}
} sgt[(C<<2)+3];
void pushdown(int pos,int le,int ri)
{
int mid = (le+ri)>>1;
if(sgt[pos].tag>-1)
{
sgt[pos<<1].sum = sgt[pos].tag*(mid-le+1); sgt[pos<<1].tag = sgt[pos].tag;
sgt[pos<<1|1].sum = sgt[pos].tag*(ri-mid); sgt[pos<<1|1].tag = sgt[pos].tag;
sgt[pos].tag = -1;
}
}
void addval(int pos,int le,int ri,int lrb,int val)
{
if(le==lrb && ri==lrb) {sgt[pos].sum += val; sgt[pos].tag = -1; return;}
pushdown(pos,le,ri);
int mid = (le+ri)>>1;
if(lrb<=mid) addval(pos<<1,le,mid,lrb,val);
else addval(pos<<1|1,mid+1,ri,lrb,val);
sgt[pos].sum = sgt[pos<<1].sum+sgt[pos<<1|1].sum;
}
void modify(int pos,int le,int ri,int lb,int rb,int val)
{
if(le>=lb && ri<=rb) {sgt[pos].sum = (ri-le+1)*val; sgt[pos].tag = val; return;}
pushdown(pos,le,ri);
int mid = (le+ri)>>1;
if(lb<=mid) {modify(pos<<1,le,mid,lb,rb,val);}
if(rb>mid) {modify(pos<<1|1,mid+1,ri,lb,rb,val);}
sgt[pos].sum = sgt[pos<<1].sum+sgt[pos<<1|1].sum;
}
int querysum(int pos,int le,int ri,int lb,int rb)
{
if(le>=lb && ri<=rb) {return sgt[pos].sum;}
pushdown(pos,le,ri);
int mid = (le+ri)>>1,ret = 0;
if(lb<=mid) {ret += querysum(pos<<1,le,mid,lb,rb);}
if(rb>mid) {ret += querysum(pos<<1|1,mid+1,ri,lb,rb);}
sgt[pos].sum = sgt[pos<<1].sum+sgt[pos<<1|1].sum;
return ret;
}
} sgt;
struct Event
{
int opt,x,y,xx,yy,ans,id; //1Õ¤À¸×ó²à£¬2Õ¤À¸ÓҲ࣬3»¨£¬4Å£
bool operator <(const Event &arg) const
{
if(x<arg.x) return true; else if(x>arg.x) return false;
if(opt>arg.opt) return true; else if(opt<arg.opt) return false;
return y>arg.y;
}
} qr[(N<<2)+3];
bool cmp_id(Event x,Event y) {return x.id<y.id;}
int id[(N<<2)+3];
set<int> s;
int n,m,p,q;
int getval(int y) //yµ½ÏÂÃæµÚÒ»¸öÅ£À¸-1µÄºÍ
{
int tmp = *s.upper_bound(y);
int ret = sgt.querysum(1,1,C,y,tmp-1);
return ret;
}
int main()
{
int q = 0;
scanf("%d",&p);
for(int i=1; i<=p; i++)
{
int lbx,rbx,lby,rby; scanf("%d%d%d%d",&lby,&lbx,&rby,&rbx);
q++; qr[q].x = lbx-1; qr[q].y = lby; qr[q].opt = 2; qr[q].id = q;
q++; qr[q].x = rbx; qr[q].y = rby; qr[q].opt = 1; qr[q].id = q;
}
scanf("%d",&m); for(int i=1; i<=m; i++) {int x,y; scanf("%d%d",&y,&x); q++; qr[q].x = x; qr[q].y = y; qr[q].opt = 3; qr[q].id = q;}
scanf("%d",&n); for(int i=1; i<=n; i++) {int x,y; scanf("%d%d",&y,&x); q++; qr[q].x = x; qr[q].y = y; qr[q].opt = 4; qr[q].id = q;}
sort(qr+1,qr+q+1); int j = q;
for(int i=1; i<=q; i++) id[qr[i].id] = i;
s.insert(C+1);
for(int i=C; i>=1; i--)
{
while(j>0 && qr[j].x==i)
{
if(qr[j].opt==2)
{
int k = id[qr[j].id+1]; int xx = qr[k].x,yy = qr[k].y,x = i,y = qr[j].y;
if(y>1)
{
int cur = getval(y-1)-qr[k].ans;
sgt.modify(1,1,C,y-1,y-1,cur);
}
sgt.modify(1,1,C,y,yy,0);
s.erase(y); if(yy<C) s.erase(yy+1);
}
else if(qr[j].opt==1)
{
int k = id[qr[j].id-1]; int x = qr[k].x,y = qr[k].y,xx = i,yy = qr[j].y;
if(y>1)
{
int cur = getval(y-1);
sgt.modify(1,1,C,y-1,y-1,cur);
}
if(yy<C) qr[j].ans = getval(yy+1);
sgt.modify(1,1,C,y,yy,0);
s.insert(y); if(yy<C) s.insert(yy+1);
}
else if(qr[j].opt==3)
{
sgt.addval(1,1,C,qr[j].y,1);
}
else if(qr[j].opt==4)
{
qr[j].ans = getval(qr[j].y);
}
j--;
}
}
sort(qr+1,qr+q+1,cmp_id);
for(int i=1; i<=q; i++) {if(qr[i].opt==4) printf("%d\n",qr[i].ans);}
return 0;
}
中考超QDEZ线\(32\)分,心里最大的一块石头终于落地了……
BZOJ 4422 Cow Confinement (线段树、DP、扫描线、差分)的更多相关文章
- 【BZOJ-4422】Cow Confinement 线段树 + 扫描线 + 差分 (优化DP)
4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 61 Solved: 26[Submi ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- 【POJ1151】Atlantis(线段树,扫描线)
[POJ1151]Atlantis(线段树,扫描线) 题面 Vjudge 题解 学一学扫描线 其实很简单啦 这道题目要求的就是若干矩形的面积和 把扫描线平行于某个轴扫过去(我选的平行\(y\)轴扫) ...
- 【Loj#535】花火(线段树,扫描线)
[Loj#535]花火(线段树,扫描线) 题面 Loj 题解 首先如果不考虑交换任意两个数这个操作,答案就是逆序对的个数. 那么暴力就是枚举交换哪个两个数,然后用数据结构之类的东西动态维护逆序对. 但 ...
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- hdu 1542 线段树之扫描线之面积并
点击打开链接 题意:给你n个矩形,求它们的面积,反复的不反复计算 思路:用线段树的扫描线完毕.将X坐标离散化后,从下到上扫描矩形,进行各种处理,看代码凝视把 #include <stdio.h& ...
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- 【POJ 2482】 Stars in Your Window(线段树+离散化+扫描线)
[POJ 2482] Stars in Your Window(线段树+离散化+扫描线) Time Limit: 1000MS Memory Limit: 65536K Total Submiss ...
随机推荐
- TableLayoutPanel
1.简单属性 百度经验:https://jingyan.baidu.com/article/9113f81b7966df2b3314c775.html Name属性:tableLayoutPanel经 ...
- 【6.28校内test】T3 【音乐会】道路千万条
[音乐会]道路千万条[题目链接] 首先,你可以忽略上面的一大坨题面,只需要看说明的那一小部分就好啦. 然后理解题意: 就是说我们要给这n-1个运算符指定一个顺序,统计所有值为true的方案数pt,统计 ...
- python爬取天气后报网
前言 大二下学期的大数据技术导论课上由于需要获取数据进行分析,我决定学习python爬虫来获取数据.由于对于数据需求量相对较大,我最终选择爬取 天气后报网,该网站可以查询到全国各地多年的数据,而且相对 ...
- POJ 2492 A Bug's Life 题解
题面 这道题是一道标准的种类并查集: 种类并查集是给每个结点一个权值.然后在合并和查找的时候根据情况对权值来进行维护. 通过将原有的区间范围变大使并查集可以维护种类的联系: #include < ...
- inline void 树状数组神奇感悟【雾
才发现扫描线可以用树状数组搞... 致远星患者 (另外根据这篇博文的内容怎么越来越感觉自己往 PJ 入门靠拢了...) 还有一点,咱把树状数组当做线段树来康的话其实一切都会很清晰,这个来张四合一的图: ...
- linux各路径(目录)的解释
目录 /bin 存放二进制可执行文件(ls,cat,mkdir等),常用命令一般都在这里. /etc 存放系统管理和配置文件 /home 存放所有用户文件的根目录,是用户主目录的基点, 比如用户use ...
- AIX 6.1创建逻辑卷并挂载【smitty】
1.创建卷组 #mkvg -y datavg hdisk2 hdisk3 #smitty vg
- mongodb,robomongo 数据查询
可视化管理工具:Robomongo 是开源,免费的MongoDB管理工具,下载地址:Robomongo下载 1. 基本查询: 构造查询数据. > db.test.findOne() ...
- navicat修改表的主键自增长报错
这周自己在构思一个项目的表的设计,由于是第一次,所以走了很多弯路,也遇到了几个问题,这里暂时贴上来. 我用PowerDesign设计出一部分关联表的ER图之后,导出了sql文件之后用navicat导入 ...
- SQLSERVER调用OPENROWSET的方法
前言:正好这两天在同步生产环境的某张表数据到测试环境,之前用过一些同步数据软件,感觉不太可靠,有时候稍有操作不当,就会出现生产环境数据被清空等情况,还要去恢复数据.如果能恢复还好,不能恢复那么.... ...