嘟嘟嘟




今天我们模拟考这题,出的是T3。实在是没想出来,就搞了个20分暴力(还WA了几发)。

这题关键在于逆向思维,就是考虑最后的\(n\)的个点刚开始在哪儿,这样就减少了很多需要维护的东西。

这就让我想到很久以前的一道NOIP题,铺地毯。那是我第一次接触逆向思维,觉得十分的巧妙,原本要写的很麻烦或者干脆写不出来的题,反着想,竟然几行就完事了。

不扯别的了,还是说一下这题怎么想吧……




把操作离线,然后倒着操作,上移变成了下移。但是每一次移动两维的坐标都会改变,十分的难受。于是我们把坐标轴旋转45度,就十分美滋滋了:以顺时针举例,如果斜率为1,在新的坐标系中只有纵坐标发生了改变;斜率为-1,只有横坐标发生了改变。而且改变的这些点一定是一个前缀或者后缀。于是更新可用线段树实现。

不过更为重要的是,对于查询的\(n\)个点,无论逆向怎么操作,这些点的横、纵坐标的相对大小都不会变,大的只会更大,小的只会更小。

有了这个性质,我们就可以二分找要改的前缀(后缀)的边界了。判断的时候就是线段树单点查询。

到这里这题基本就完事了,需要注意的是,区间修改时应该加(减)的是\(2l\),因为在原本的坐标系中移动的距离是\(\sqrt{2} l\),而新坐标系的距离又是原来的\(\sqrt{2}\)倍,所以应该是\(\sqrt{2} * \sqrt{2}l\)。




线段树有点慢,需要开O2才能过,改成树状数组就快很多了。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define space putchar(' ')
#define enter puts("")
#define Mem(a, x) memset(a, x, sizeof(x))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 4e5 + 5;
const int N = 262144;
In ll read()
{
ll ans = 0;
char ch = getchar(), las = ' ';
while(!isdigit(ch)) las = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(las == '-') ans = -ans;
return ans;
}
In void write(ll x)
{
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
} int n, Q;
struct Que
{
int d; ll x, l;
}q[maxn]; struct Tree
{
int l[maxn << 2], r[maxn << 2];
ll lzy[maxn << 2];
In void build(int L, int R, int now, int flg)
{
l[now] = L; r[now] = R;
if(L == R) {lzy[now] = L * flg; return;}
int mid = (L + R) >> 1;
build(L, mid, now << 1, flg);
build(mid + 1, R, now << 1 | 1, flg);
}
In void pushdown(int now)
{
if(lzy[now])
{
lzy[now << 1] += lzy[now]; lzy[now << 1 | 1] += lzy[now];
lzy[now] = 0;
}
}
In void update(int L, int R, int now, int d)
{
if(l[now] == L && r[now] == R)
{
lzy[now] += d;
return;
}
pushdown(now);
int mid = (l[now] + r[now]) >> 1;
if(R <= mid) update(L, R, now << 1, d);
else if(L > mid) update(L, R, now << 1 | 1, d);
else update(L, mid, now << 1, d), update(mid + 1, R, now << 1 | 1, d);
}
In ll query(int now, int id)
{
if(l[now] == r[now]) return lzy[now];
pushdown(now);
int mid = (l[now] + r[now]) >> 1;
if(id <= mid) return query(now << 1, id);
else return query(now << 1 | 1, id);
}
}t1, t2; int main()
{
n = read(), Q = read();
for(int i = Q; i; --i) q[i].x = read(), q[i].d = read(), q[i].l = read();
t1.build(0, N - 1, 1, 1), t2.build(0, N - 1, 1, -1);
for(int i = 1; i <= Q; ++i)
{
if(q[i].d == 1)
{
int L = 0, R = N - 1;
while(L < R)
{
int mid = ((L + R) >> 1) + 1;
if(t2.query(1, mid) < -q[i].x) R = mid - 1;
else L = mid;
}
t1.update(0, L, 1, -q[i].l * 2);
}
else
{
int L = 0, R = N - 1;
while(L < R)
{
int mid = ((L + R) >> 1) + 1;
if(t1.query(1, mid) > q[i].x) R = mid - 1;
else L = mid;
}
if(L + 1 > N - 1) --L;
t2.update(L + 1, N - 1, 1, -q[i].l * 2);
}
}
for(int i = 1; i <= n; ++i) write(-(t2.query(1, i) + t1.query(1, i)) / 2), enter;
return 0;
}

「JOI 2016 Final」断层的更多相关文章

  1. Luogu P5103 「JOI 2016 Final」断层 树状数组or线段树+脑子

    太神仙了这题... 原来的地面上升,可以倒着操作(时光倒流),转化为地面沉降,最后的答案就是每个点的深度. 下面的1,2操作均定义为向下沉降(与原题意的变换相反): 首先这个题目只会操作前缀和后缀,并 ...

  2. LOJ#2343. 「JOI 2016 Final」集邮比赛 2

    题目地址 https://loj.ac/problem/2343 题解 首先处理出\(f[i]\)表示以当前位置开头(J,O,I)的合法方案数.这个显然可以\(O(n)\)处理出来.然后考虑在每个位置 ...

  3. LOJ#2351. 「JOI 2018 Final」毒蛇越狱

    LOJ#2351. 「JOI 2018 Final」毒蛇越狱 https://loj.ac/problem/2351 分析: 首先有\(2^{|?|}\)的暴力非常好做. 观察到\(min(|1|,| ...

  4. 「JOI 2017 Final」JOIOI 王国

    「JOI 2017 Final」JOIOI 王国 题目描述 题目译自 JOI 2017 Final T3「 JOIOI 王国 / The Kingdom of JOIOI」 JOIOI 王国是一个 H ...

  5. 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)

    LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...

  6. 【题解】LOJ2759. 「JOI 2014 Final」飞天鼠(最短路)

    [题解]LOJ2759. 「JOI 2014 Final」飞天鼠(最短路) 考虑最终答案的构成,一定是由很多飞行+一些上升+一些下降构成. 由于在任何一个点上升或者下降代价是一样的,所以: 对于上升操 ...

  7. 「JOI 2014 Final」飞天鼠

    「JOI 2014 Final」飞天鼠 显然向上爬是没有必要的,除非会下降到地面以下,才提高到刚好为0. 到达一个点有两种情况:到达高度为0和不为0. 对于高度不为0的情况,显然花费的时间越少高度越高 ...

  8. 「JOI 2015 Final」城墙

    「JOI 2015 Final」城墙 复杂度默认\(m=n\) 暴力 对于点\((i,j)\),记录\(ld[i][j]=min(向下延伸的长度,向右延伸的长度)\),\(rd[i][j]=min(向 ...

  9. 「JOI 2015 Final」舞会

    「JOI 2015 Final」舞会 略微思考一下即可知该过程可以化为一棵树.(3个贵族中选择1个,即新建一个节点连向这3个贵族). 该树的结点个数为\(2n\). 考虑二分答案mid. 判定的是公主 ...

随机推荐

  1. 【读书笔记】iOS-使用钥匙串保护数据

    一,将应用从设备上删除时,并不会删除其钥匙串项,这使得调试工作困难得多.模拟器有一个Reset Contents and Settings选项,可用于将钥匙串项移除.因此,强烈建议在模拟器上确定Key ...

  2. CSS超全笔记(适合新手入门)

    CSS CSS初识 CSS(Cascading Style Sheets) 美化样式 CSS通常称为CSS样式表或层叠样式表(级联样式表),主要用于设置HTML页面中的文本内容(字体.大小.对齐方式等 ...

  3. 33.Odoo产品分析 (四) – 工具板块(4) – 问题追踪及群发邮件营销(1)

    查看Odoo产品分析系列--目录 问题追踪 该应用程序允许您管理项目中可能遇到的问题,如系统中的bug.客户投诉或物料故障.  该模块安装后没有菜单显示,而是作为后台管理,接收一些问题报告. 群发邮件 ...

  4. 父类通过泛型获得子类Class类型 以及Type体系

    1.背景介绍 在实现SSH框架中,DAO层向数据库持久化的过程中,因为大部分保存对象的方法都会调用到sava():所有索性就把save delete update select 方法进行封装到父类中, ...

  5. Python property使用简介

    property使用简介 by:授客 QQ:1033553122 功能简介 1) 把类方法变成只读属性 2) setter和getter的另一种实现 代码演示1 #!/usr/bin/env pyth ...

  6. leetcode-978. 最长湍流子数组

    leetcode-978. 最长湍流子数组 Points 数组 DP 题意 当 A 的子数组 A[i], A[i+1], ..., A[j] 满足下列条件时,我们称其为湍流子数组: 若 i <= ...

  7. eclipse安装中java环境的搭建

    转自博客园:amandaj  做了小小改动. 一.java 开发环境的搭建 这里主要说的是在windows 环境下怎么配置环境. 1.首先安装JDK java的sdk简称JDK ,去其官方网站下载最近 ...

  8. 使用MUI/html5plus集成微信支付需要注意的几点问题

    1)需要在服务器根目录放上证书,从微信开放平台下载 2)客户端组件目录名一定要按照微信要求

  9. 在 Centos 安装 MySQL

    MySQL是开源的数据库管理系统,通常作为LEMP(Linux, Nginx, MySQL/MariaDB, PHP/Python/Perl)技术栈的一部分,而被安装.RedHat 会害怕 Oracl ...

  10. Android/IOS手机使用Fiddler抓包

    对于Android和IOS开发及测试的同事来说抓包是一个很重要的事,有利于排查问题所在,快速定位问题.但长期以来一直没有一款可以快速抓包的工具,直到有了Fiddler2. 使用步骤: 1.  Fidd ...