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(向 ...
随机推荐
- BZOJ3700: 发展城市
BZOJ3700: 发展城市 https://lydsy.com/JudgeOnline/problem.php?id=3700 分析: 枚举两个人,先求链交,求到两个端点的时间. 链交求法:求两两\ ...
- 多版本Python共存时pip给指定版本的python安装package的方法
在Linux安装了多版本Python时(例如python2.7和3.6),pip安装的包不一定是用户想要的位置,此时可以用 -t 选项来指定位置. 例如目标位置是/usr/local/lib/pyth ...
- linux shell查询
查看当前版本可用的shell cat /etc/shells 查看当前使用的shell echo $0 查看当前用户默认使用的shell echo $SHELL
- redhat 安装lamp
安装Apache yum install httpd 安装MySql yum install mysql mysql-server 安装php yum install php 安装php的mysql模 ...
- Azure xplate cli创建虚拟机
Azure的管理工具多种多样.其中Portal和PowerShell是经常使用的. 但用MAC和Linux的同学最喜欢的还是Bash环境. Azure也提供了跨平台的命令行工具:Azure xplat ...
- 统计不同的单词(map应用)
题目描述: 输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本中的另一个单词.在判断是否满足条件时,字母不区分大小写,但在输出时应保留输入中的大小写,按字典序进行排列(所有 ...
- JVM体系结构之五:本地方法栈
对于一个运行中的Java程序而言,它还可能会用到一些跟本地方法相关的数据区.当某个线程调用一个本地方法时,它就进入了一个全新的并且不再受虚拟机限制的世界.本地方法可以通过本地方法接口来访问虚拟机的运行 ...
- mariadb的读写分离
实验环境:CentOS7 设备:一台主数据库服务器,两台从数据库服务器,一台调度器 主从的数据库配置请查阅:http://www.cnblogs.com/wzhuo/p/7171757.html : ...
- SQL连接、嵌套和集合查询---
SQL连接.嵌套和集合查询 一:连接查询 1 .不同表之间的连接查询 例 查询每个学生及其选修课程的情况. 本查询实际上是涉及Students与Reports两个表的连接操作.这两个表之间的联系是通过 ...
- Centos开启telnet/ssh/ftp/sftp服务
Telnet 开启telnet服务步骤: 1. 查看CentOS/Telnet_server版本:#cat /etc/issue, #rpm -qa | grep telnet 2. 安装 ...