HDU 6089 Rikka with Terrorist (线段树)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=6089
题解
这波强行维护搞得我很懵逼。。。
扫描线,只考虑每个点能走到左上方(不包括正上方,但包括正左方)的哪些点,然后旋转四次坐标系处理
所有询问和操作点按照先\(x\)后\(y\)坐标的顺序排序,然后枚举每一行,按\(y\)从小到大的顺序枚举这一行每个点
对于一个询问点找出前面最后一个操作点,那么要求的就是一个矩形减去一个区间内所有后缀最大值的和
然后这个东西可以用线段树直接维护,记录个区间最大值然后pushup的时候二分
操作点就相当于单点修改
时间复杂度\(O(n\log^2n)\).
代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<utility>
#include<algorithm>
#define llong long long
#define pll pair<llong,llong>
#define mkpr make_pair
using namespace std;
const int N = 1e5;
struct SegmentTree
{
struct SgTNode
{
llong maxi,psum;
} sgt[(N<<2)+3];
void clear(int u,int le,int ri)
{
sgt[u].maxi = sgt[u].psum = 0;
if(le==ri) return;
int mid = (le+ri)>>1;
clear(u<<1,le,mid); clear(u<<1|1,mid+1,ri);
}
llong calc(int u,int le,int ri,llong x)
{
if(le==ri) {return sgt[u].maxi<x ? x : sgt[u].maxi;}
int mid = (le+ri)>>1;
if(sgt[u<<1|1].maxi<x) {return calc(u<<1,le,mid,x)+x*(ri-mid);}
else {return sgt[u].psum-sgt[u<<1|1].psum+calc(u<<1|1,mid+1,ri,x);} //Note here!
}
void pushup(int u,int le,int ri)
{
int mid = (le+ri)>>1;
sgt[u].maxi = max(sgt[u<<1].maxi,sgt[u<<1|1].maxi);
sgt[u].psum = calc(u<<1,le,mid,sgt[u<<1|1].maxi)+sgt[u<<1|1].psum;
}
void modify(int u,int le,int ri,int pos,llong x)
{
if(le==pos && ri==pos) {sgt[u].maxi = sgt[u].psum = x; return;}
int mid = (le+ri)>>1;
if(pos<=mid) {modify(u<<1,le,mid,pos,x);}
else {modify(u<<1|1,mid+1,ri,pos,x);}
pushup(u,le,ri);
}
pll query(int u,int le,int ri,int lb,int rb,llong x)
{
if(lb>rb) {return make_pair(0,0);}
if(le>=lb && ri<=rb) {return make_pair(max(sgt[u].maxi,x),calc(u,le,ri,x));}
int mid = (le+ri)>>1;
if(rb<=mid) {return query(u<<1,le,mid,lb,rb,x);}
else if(lb>mid) {return query(u<<1|1,mid+1,ri,lb,rb,x);}
else
{
pll retr = query(u<<1|1,mid+1,ri,lb,rb,x);
pll retl = query(u<<1,le,mid,lb,rb,retr.first);
return mkpr(retl.first,retl.second+retr.second);
}
}
} sgt;
struct Query
{
int x,y,id;
Query() {}
Query(int _x,int _y,int _id) {x = _x,y = _y,id = _id;}
bool operator <(const Query &arg) const
{
return x<arg.x || (x==arg.x && y<arg.y);
}
};
llong fans[N+3];
int mx[N+3];
namespace Solve
{
Query qr[(N<<1)+3];
int q;
int nx,ny;
void addquery(int x,int y,int id) {q++; qr[q] = Query(x,y,id);}
void solve()
{
sort(qr+1,qr+q+1); int j = 1; while(j<=q && qr[j].x==0) j++;
for(int i=1; i<=nx; i++)
{
int k = 0;
while(j<=q && qr[j].x==i)
{
if(qr[j].id==0)
{
sgt.modify(1,1,ny,qr[j].y,i);
k = qr[j].y; mx[qr[j].y] = i;
}
else
{
llong ans = (llong)i*(qr[j].y-1-k)-sgt.query(1,1,ny,k+1,qr[j].y-1,mx[qr[j].y]).second; //Note here!
fans[qr[j].id] += ans;
}
j++;
}
}
q = 0; sgt.clear(1,1,ny); for(int i=1; i<=ny; i++) mx[i] = 0ll;
}
}
Query a[N+3],b[N+3];
int nx,ny,m,q;
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%d%d%d%d",&nx,&ny,&m,&q);
for(int i=1; i<=m; i++) scanf("%d%d",&a[i].x,&a[i].y);
for(int i=1; i<=q; i++) scanf("%d%d",&b[i].x,&b[i].y);
//1
Solve::nx = nx; Solve::ny = ny;
for(int i=1; i<=m; i++) Solve::addquery(a[i].x,a[i].y,0);
for(int i=1; i<=q; i++) Solve::addquery(b[i].x,b[i].y,i);
Solve::solve();
//2
Solve::nx = ny; Solve::ny = nx;
for(int i=1; i<=m; i++) Solve::addquery(a[i].y,nx+1-a[i].x,0);
for(int i=1; i<=q; i++) Solve::addquery(b[i].y,nx+1-b[i].x,i);
Solve::solve();
//3
Solve::nx = nx; Solve::ny = ny;
for(int i=1; i<=m; i++) Solve::addquery(nx+1-a[i].x,ny+1-a[i].y,0);
for(int i=1; i<=q; i++) Solve::addquery(nx+1-b[i].x,ny+1-b[i].y,i);
Solve::solve();
//4
Solve::nx = ny; Solve::ny = nx;
for(int i=1; i<=m; i++) Solve::addquery(ny+1-a[i].y,a[i].x,0);
for(int i=1; i<=q; i++) Solve::addquery(ny+1-b[i].y,b[i].x,i);
Solve::solve();
for(int i=1; i<=q; i++) printf("%lld\n",fans[i]+1);
memset(fans,0,sizeof(fans));
}
return 0;
}
HDU 6089 Rikka with Terrorist (线段树)的更多相关文章
- hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
- HDU 5634 Rikka with Phi 线段树
题意:bc round 73 div1 D 中文题面 分析:注意到10^7之内的数最多phi O(log(n))次就会变成1, 因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护. 每次求p ...
- HDU 5828 Rikka with Sequence (线段树+剪枝优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...
- HDU 5828 Rikka with Sequence(线段树区间加开根求和)
Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...
- 2016暑假多校联合---Rikka with Sequence (线段树)
2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...
- HDU5634 Rikka with Phi 线段树
// HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
随机推荐
- 【转】.NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现
作者:Zhang_Xiang 原文地址:.NET Core + Ocelot + IdentityServer4 + Consul 基础架构实现 先决条件 关于 Ocelot 针对使用 .NET 开发 ...
- JVM 线上故障排查基本操作 (转)
前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该如何 ...
- Docker 数据卷与容器互联
Docker是基于Go语言实现的开源容器项目,Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制, ...
- poj 4005 Moles
大意: 给定$n$元素序列$a$, 依次插入二叉搜索树, 求出$dfs$序列, 对序列每个元素模$2$得到一个长为$2n-1$的$01$序列$s1$. 再给定$01$序列$s2$, 求$s2$在$s1 ...
- dubbo学习笔记四(异步调用)
相关资料 官方文档 项目结构 代码示例 [EchoTestApp] @RestController @SpringBootApplication @ImportResource("class ...
- Nginx编译参数详解
Nginx编译参数 1.当我们安装好nginx后,输入命令 nginx -V 可以看到nginx的编译参数信息,例如 如下图 2. 编译参数如下图 # Nginx安装目的目录或路径 --prefix ...
- 在iPhone开发中实现解压缩gzip
在iPhone开发中实现解压缩gzip是本文要介绍的内容,最近做的一个东西中,需要从网络获取xml文件,但是该文件用了gzip压缩的.搜索一 下有人说gzip压缩的用urlrequest可以自己解压, ...
- pip 报错找不到pip问题
具体报错如下 解决办法: wget https://bootstrap.pypa.io/get-pip.py --no-check-certificate 使用当前python3运行
- python之SSH远程登录
一.SSH简介 SSH(Secure Shell)属于在传输层上运行的用户层协议,相对于Telnet来说具有更高的安全性. 二.SSH远程连接 SSH远程连接有两种方式,一种是通过用户名和密码直接登录 ...
- deep_learning_Function_tf.add()、tf.subtract()、tf.multiply()、tf.div()
tf.add().tf.subtract().tf.multiply().tf.div()函数介绍和示例 1. tf.add() 释义:加法操作 示例: x = tf.constant(2, dtyp ...