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 ...
随机推荐
- Android新版xUtils3工具类相关debug
首先出现问题是 build.gradle中的csayısıom.lidroid.xutils:xutils:2.6.13报错了,所以想到是版本的问题,github上搜了xutils发现有新版xutil ...
- Buy a Ticket CodeForces - 938D (dijkstra)
大意: n节点无向图, 点$i$到点$j$的花费为$2dis(i,j)+a[j]$, 对于每个点, 求最少花费. 每条边权翻倍, 源点S向所有点$i$连边, 权为$a[i]$, 答案就为$S$到每个点 ...
- 07 MySQL之索引原理
一.介绍 为什么有索引:使用索引可快速访问数据库表中的特定信息.索引是对数据库表中一列或多列的值进行排序的一种结构. 作用: 1. 快速查询数据 2. 保证数据的唯一性 3 ...
- python django网站编程视频教程学习资料下载
“人生苦短,我用python”,学python的小伙伴应该都了解这句话的含义.但是,学python,你真正了了解强大的Django框架吗!?据说Django还是由吉普赛的一个吉他手的名字命名的呢,有木 ...
- Windwos Java‘bat 环境变量配置脚本
@echo off echo 正在设置Java环境变量 pause wmic ENVIRONMENT create name="JAVA_HOME",username=" ...
- 如何删掉git版本库master分支的第一个commit
这个操作会将库清空,一般来说在建库开始的时候操作. 适用场景: git init初始化版本库之后,提交第一个点之后发现这个点出问题了,但是此时内心如果有洁癖的话, 你会觉得不完美,很想把这个点干掉重来 ...
- 标准C语言(7)
函数调用过程中通常伴随着两个函数之间的数据传递.数据传递存在两个完全相反的方向(可以从调用函数,向被调用函数传递数据也可以从被调用函数向,调用函数传递数据),任意方向的数据传递都使用被调用函数提供的存 ...
- php页面加载完毕后再显示购买按钮
php页面加载完毕后再显示购买按钮 $document.ready(function(){ $("#buybotton").show()})
- BZOJ1791 基环树直径
非递归版4S /************************************************************** Problem: 1791 User: 18357 Lan ...
- Mongodb数据模型
描述表关系的方式: 方式一:嵌入式 > db.person.find({name:'zjf'}).pretty() { "_id" : ObjectId("592f ...