题目链接

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 (线段树)的更多相关文章

  1. hdu 5828 Rikka with Sequence 线段树

    Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...

  2. HDU 5634 Rikka with Phi 线段树

    题意:bc round 73 div1 D 中文题面 分析:注意到10^7之内的数最多phi O(log(n))次就会变成1, 因此可以考虑把一段相同的不为1的数缩成一个点,用平衡树来维护. 每次求p ...

  3. HDU 5828 Rikka with Sequence (线段树+剪枝优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5828 给你n个数,三种操作.操作1是将l到r之间的数都加上x:操作2是将l到r之间的数都开方:操作3是 ...

  4. HDU 5828 Rikka with Sequence(线段树区间加开根求和)

    Problem DescriptionAs we know, Rikka is poor at math. Yuta is worrying about this situation, so he g ...

  5. 2016暑假多校联合---Rikka with Sequence (线段树)

    2016暑假多校联合---Rikka with Sequence (线段树) Problem Description As we know, Rikka is poor at math. Yuta i ...

  6. HDU5634 Rikka with Phi 线段树

    // HDU5634 Rikka with Phi 线段树 // 思路:操作1的时候,判断一下当前区间是不是每个数都相等,在每个数相等的区间上操作.相当于lazy,不必更新到底. #include & ...

  7. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  8. HDU.5692 Snacks ( DFS序 线段树维护最大值 )

    HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...

  9. HDU.1556 Color the ball (线段树 区间更新 单点查询)

    HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...

随机推荐

  1. 【2017.12.02】C组比赛总结

    这次考得不怎么样,只有200分! T1:读书 这题水水水! 这题就是一道循环题嘛! 直接一边循环一边做就好了! T2:恐怖分子 这题我是直接暴力的. 这题就是求至少用多少条经过(x0,y0)的不同直线 ...

  2. Arkady and a Nobody-men CodeForces - 860E (虚树)

    大意: 给定有根树, 根节点深度为$1$. 定义$r(a,b)$为$b$子树内深度不超过$a$的节点数$-1$ 定义$z_a$为$a$的所有祖先的$r$之和. 对于所有点求出$z$的值. 一个点$y$ ...

  3. 提升scrapy的爬取效率

    增加并发: 默认scrapy开启的并发线程为32个,可以适当进行增加.在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100. 降低日志级别 ...

  4. 100、神器的 routing mesh (Swarm07)

    参考https://www.cnblogs.com/CloudMan6/p/7930321.html   上一节我们提到了 swarm 的 routing mesh .当外部访问任意节点的8080端口 ...

  5. Altium Designer 只导出PCB元器件及标号的PDF文件的方法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明. 作者:struct_mooc 博客地址:https://www.cnblogs.com/stru ...

  6. Linux Exploit系列之六 绕过ASLR - 第一部分

    绕过ASLR - 第一部分 什么是 ASLR? 地址空间布局随机化(ASLR)是随机化的利用缓解技术: 堆栈地址 堆地址 共享库地址 一旦上述地址被随机化,特别是当共享库地址被随机化时,我们采取的绕过 ...

  7. Nginx默认配置语法

    Nginx默认配置语法 1. 我们进入  /etc/nginx/目录下,打开  nginx.conf文件 2. 我们来解析下 这里面标签和各模块的作用 # 设置nginx服务的系统使用用户 user ...

  8. Redhat 7修改主机名

    修改主机名: Linux master2 3.10.0-693.el7.x86_64 #1 SMP Thu Jul 6 19:56:57 EDT 2017 x86_64 x86_64 x86_64 G ...

  9. centos6和centos7的区别和常用的简单配置优化

    - 本节主要介绍centos6和centos7的区别和常用的简单配置优化:- 第一部分: - 1.对比文件系统 - 2.对比防火墙,内核版本,默认数据库 - 3.对比时间同步,修改时区,修改语言 - ...

  10. Go语言标准库之fmt.Scan

    Go语言fmt.Scan使用指南 本文介绍了Go语言中fmt包中从标准输入获取数据的的Scan系列函数.从io.Reader中获取数据的Fscan系列函数以及从字符串中获取数据的Sscan系列函数的用 ...