Luogu P5103 「JOI 2016 Final」断层 树状数组or线段树+脑子
太神仙了这题。。。
原来的地面上升,可以倒着操作(时光倒流),转化为地面沉降,最后的答案就是每个点的深度。
下面的1,2操作均定义为向下沉降(与原题意的变换相反);
首先这个题目只会操作前缀和后缀,并且只会把前缀中的数(纵坐标)变小(2操作),后缀中的数(横坐标)变大(1操作),所以具有单调性,可以进行二分。(括号中含义的解释见下)
先把整个坐标系旋转$45$度(逆时针为例),操作1即纵坐标$y>=xi$的点都会往右走$2*l$,横坐标$+2*l$,纵坐标不变,由于有单调性,只会操作后缀;操作2即横坐标$x<=xi$的点都会往下走$2*l$,纵坐标$-2*l$,横坐标不变,由于有单调性,只会操作前缀。
所以二分一下实际坐标就好了。。注意最后计算深度是$(x-y)/2$
我的这种二分需要维护一个$mx$区间最大值,二分时看一眼左右子树的$mx$,然后决定向哪一棵子树递归。
#include<cstdio>
#include<iostream>
#define ls (tr<<1)
#define rs (tr<<1|1)
#define ll long long
#define R register ll
const int N=,Inf=0x3f3f3f3f;
using namespace std;
char B[<<],*S=B,*T=B,ch;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
int n,m;
struct node {int x,d,l;}q[N];
ll MX[][N<<],TG[][N<<];
#define mx MX[c]
#define tg TG[c]
inline void build(int c,int tr,int l,int r) {
if(l==r) {mx[tr]=l; return ;} R md=l+r>>;
build(c,ls,l,md),build(c,rs,md+,r); mx[tr]=max(mx[ls],mx[rs]);
}
inline void spread(int c,int tr) { if(!tg[tr]) return ;
tg[ls]+=tg[tr],tg[rs]+=tg[tr],mx[ls]+=tg[tr],mx[rs]+=tg[tr]; tg[tr]=;
} ll pos;
inline void fx(int tr,int l,int r,int k) {
if(l==r) {if(MX[][tr]<=k) pos=max(pos,(ll)l); return ;} spread(,tr); R md=l+r>>;
if(MX[][ls]<=k) pos=max(pos,md),fx(rs,md+,r,k); else fx(ls,l,md,k);
}
inline void fy(int tr,int l,int r,int k) {
if(l==r) {if(MX[][tr]>k) pos=min(pos,(ll)l); return ;} spread(,tr); R md=l+r>>;
if(MX[][ls]<=k) fy(rs,md+,r,k); else fy(ls,l,md,k);
}
inline void add(int c,int tr,int l,int r,int LL,int RR,int d) {
if(LL<=l&&r<=RR) {mx[tr]+=d,tg[tr]+=d; return ;} spread(c,tr); R md=l+r>>;
if(LL<=md) add(c,ls,l,md,LL,RR,d); if(RR>md) add(c,rs,md+,r,LL,RR,d); mx[tr]=max(mx[ls],mx[rs]);
} ll p[][N];
inline void calc(int c,int tr,int l,int r) {
if(l==r) {p[c][l]=mx[tr]; return ;} spread(c,tr);
R md=l+r>>; calc(c,ls,l,md),calc(c,rs,md+,r);
}
signed main() { freopen("geologic.in","r",stdin); freopen("geologic.out","w",stdout);
n=g(),m=g(); for(R i=;i<=m;++i) q[i].x=g(),q[i].d=g(),q[i].l=g();
build(,,,n),build(,,,n); for(R i=m;i>=;--i) {
if(q[i].d==) {
pos=; fx(,,n,q[i].x);
if(pos) add(,,,n,,pos,-*q[i].l);
} else {
pos=Inf; fy(,,n,q[i].x);
if(pos!=Inf) add(,,,n,pos,n,*q[i].l);
} //cerr<<pos<<endl;
} calc(,,,n),calc(,,,n);
for(R i=,ans;i<=n;++i) ans=(p[][i]-p[][i])/,printf("%lld\n",ans);
}
这还有一个不旋转坐标的,具体的就是类似直接模拟,但是难度在如何二分位置;
想一想发现:这不是直线方程么。。。
所以还是分别维护横纵坐标,但是二分条件改成$y>=x-xi$即$x-y<=xi$或$y>=-x+xi$即$x+y>=xi$;
#include<cstdio>
#include<iostream>
#define ll long long
#define R register ll
const int M=;
char B[<<],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
using namespace std;
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
} ll x[M],y[M],ans[M];
inline int fx(ll d) { R pos=,t;
for(R i=;~i;--i) if((t=x[pos+(<<i)]-y[pos+(<<i)])<=d) pos+=(<<i),d-=t; return pos;
}
inline int fy(ll d) { R pos=,t;
for(R i=;~i;--i) if((t=x[pos+(<<i)]+y[pos+(<<i)])<=d) pos+=(<<i),d-=t; return pos;
} int n,m;
inline void add(int pos,int incx,int incy) {for(;pos<M;pos+=pos&-pos) x[pos]+=incx,y[pos]+=incy;}
struct node {int x,d,l;} q[M];
signed main() { freopen("geologic.in","r",stdin); freopen("geologic.out","w",stdout);
n=g(),m=g(); for(R i=;i<=n;++i) add(i,,);
for(R i=;i<=m;++i) q[i].x=g(),q[i].d=g(),q[i].l=g();
for(R i=m;i;--i) if(q[i].d==) {
R pos=fx(q[i].x); if(pos) add(,-q[i].l,-q[i].l),add(pos+,q[i].l,q[i].l);
} else { R pos=fy(q[i].x); if(pos<n) add(pos+,q[i].l,-q[i].l);}
for(R i=;i<=n;++i) {
ans[i]=ans[i-(i&-i)]+y[i];
printf("%lld\n",-ans[i]);
}
}
2019.06.01 June
Luogu P5103 「JOI 2016 Final」断层 树状数组or线段树+脑子的更多相关文章
- 「JOI 2016 Final」断层
嘟嘟嘟 今天我们模拟考这题,出的是T3.实在是没想出来,就搞了个20分暴力(还WA了几发). 这题关键在于逆向思维,就是考虑最后的\(n\)的个点刚开始在哪儿,这样就减少了很多需要维护的东西. 这就让 ...
- LOJ#2343. 「JOI 2016 Final」集邮比赛 2
题目地址 https://loj.ac/problem/2343 题解 首先处理出\(f[i]\)表示以当前位置开头(J,O,I)的合法方案数.这个显然可以\(O(n)\)处理出来.然后考虑在每个位置 ...
- HDU 5877 2016大连网络赛 Weak Pair(树状数组,线段树,动态开点,启发式合并,可持久化线段树)
Weak Pair Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Tota ...
- LOJ#2351. 「JOI 2018 Final」毒蛇越狱
LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...
- 「JOI 2017 Final」JOIOI 王国
「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...
- 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)
LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...
- 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)
[题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...
- 「JOI 2014 Final」飞天鼠
「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...
- 「JOI 2015 Final」城墙
「JOI 2015 Final」城墙 复杂度默认\(m=n\) 暴力 对于点\((i,j)\),记录\(ld[i][j]=min(向下延伸的长度,向右延伸的长度)\),\(rd[i][j]=min(向 ...
随机推荐
- noip2017列队(线段树)
维护一个方阵,支持 1.删掉一个点,剩下的点先向左看齐再向前看齐 2.询问一个位置上是哪个点 $n,m,q \leq 3 \times 10^5$ sol: 我们每行前$m-1$列维护一个线段树,最后 ...
- Python:easygui的安装、导入、使用、设置
转于:https://blog.csdn.net/sinat_37390744/article/details/55211652 博主:钏的博客 一.下载安装 1)下载0.96的easygui.htt ...
- 微服务理论之三:RPC框架原理
RPC调用是面向服务架构场景下进行服务间调用的常用组件,一个完整的RPC调用的流程如图1所示: 图1 RPC调用流程 为了方便RPC调用者和服务者的开发,开发者们开发了很多RPC框架.比较有名的RPC ...
- svn、git等比较---总结
免费的版本控制系统: CVS:集中式的版本控制系统,必须联网,速度慢,CVS作为最早的开源而且免费的集中式版本控制系统,直到现在还有不少人在用.由于CVS自身设计的问题,会造成提交文件不完整,版本库莫 ...
- Nmap几个常用的参数
Nmap扫描端口的6种状态: open:端口是开放的 closed:端口是关闭的 filtered:端口被防火墙IDS/IPS屏蔽,无法确定其状态 unfiltered:端口没有被屏蔽,但要进一步确定 ...
- C++ 替换字符串内某个字符或子串
1. 问题描述 string s="abc"; string tmp="1"; 2.解决方案 // tmp 必须为字符串 // 第一个 1 表示 s 中的位置 ...
- SSDB VS redis
现在有不少团队开始使用了一个新型高效的 NoSQL数据库 - SSDB,如 京东.唱吧 …… SSDB 官网的定义 一个高性能的支持丰富数据结构的 NoSQL 数据库,用于替代 Redis 官网 ht ...
- [poj1737]Connected Graph(连通图计数)
题意:输出题中带有$n$个标号的图中连通图的个数. 解题关键: 令$f(n)$为连通图的个数,$g(n)$为非联通图的个数,$h(n)$为总的个数. 则$f(n) + g(n) = h(n)$ 考虑标 ...
- MQTT,XMPP,STOMP,AMQP,WAMP适用范围优缺点比较
想要向服务器发送请求并获得响应?直接使用 HTTP 吧!非常简单.但是当需要通过持久的双向连接来通信时,如 WebSockets,当然你也有其它的选择. 这篇文章会简单扼要的解释 MQTT,XMPP, ...
- 荧光分子的dynamic quenching 和 通常说的quenching的区别?
quenching有两种,学术上分为dynamic quenching 和static quenching,我们通常说的quenching就是 static quenching. static que ...