倍增st表

news/2024/10/22 21:12:25


首先,因为士兵是环形的,所以先将其拆分为链,并且每个士兵的移动位子不会被包含,所以只需要对左端点进行排序就能得到一个递增的区间

点击查看代码
void init()
{cin >> n >> m;int i;for (i = 1; i <= n; ++i){w[i].i1 = i;cin >> w[i].l >> w[i].r;if (w[i].r < w[i].l)//如果右端点小于左端点,加上m,让成为链的时候右端点在左端点的右边w[i].r += m;}sort(w + 1, w + n + 1);//根据左端点进行排序n2 = n * 2;i = n + 1;for (i; i <= n2; i++)//复制一份{w[i].i1 = w[i - n].i1;w[i].l = w[i - n].l + m;w[i].r = w[i - n].r + m;}
}

之后如此图,

如果a是一点要选的话,那么根据贪心,下一个选择最好的方案就是c,也就是在左端点小于当前右端点的情况下,右端点最远的点,此时我们假设a(f,j)为战士在f点跑2的j次方到达的边防站,那就可以转化为a(a(f,j-1),j-1)到达的边防站,(2的n次方=2的(n-1)次方*2)因为 2的20次方为1000000,够用了,所以我们以此预处理每组数据

点击查看代码
void st()
{int o = 1;for (int i = 1; i <= n2; ++i){while (o <= n2 && w[o].l <= w[i].r)o++;a[i][0] = o - 1; // 找到左端点小于当前i的右端点且右端点最远的点}for (int i = 1; (1 << i) <= n; ++i)//i相当于从s点走了2的i次{for (int s = 1; s <= n2; ++s){a[s][i] = a[a[s][i - 1]][i - 1];//公式}}
}
最后,要知道最少要多少战士,我们先根据当前战士的左端下标来确定最右端下标//之后从最大值开始遍历,如果x走2的i次方步存在最优点(就是预处理代码每个点选择的下一个最优点),那答案就可以加上当前点,并且之后now更新为当前的最优点,再由不断更新的最优点到达计划点。最后ans还要+1,因为for里到达的最远点是小于计划到达的最远点的,必须要再加一个点才能大于计划点(为什么只加1呢,因为如果还能加,那for循环就没有结束) 完整代码
点击查看代码
/* 台州第一深情 */
#include <iostream>      // 输入输出流
#include <iomanip>       // 输入输出格式控制
#include <fstream>       // 文件输入输出流
#include <sstream>       // 字符串输入输出流
#include <cmath>         // 数学函数
#include <string>        // 字符串操作
#include <vector>        // 动态数组容器
#include <queue>         // 队列容器
#include <stack>         // 栈容器
#include <set>           // 集合容器
#include <map>           // 映射容器
#include <unordered_set> // 无序集合容器
#include <unordered_map> // 无序映射容器
#include <algorithm>     // 算法
#include <bitset>        // 位集容器
#include <stdio.h>       // 标准输入输出
using namespace std;
using i64 = long;
// using int = long long;
typedef pair<int, int> PII;
const int N = 4e5 + 10;
int n1;
struct vv
{int i1, l, r;bool operator<(const vv &b) const { return l < b.l; }
} w[2 * N]; // 将环形记录成链
int a[N][25];
int res[N];
int n, m, n2;void init()
{cin >> n >> m;int i;for (i = 1; i <= n; ++i){w[i].i1 = i;cin >> w[i].l >> w[i].r;if (w[i].r < w[i].l) // 如果右端点小于左端点,加上m,让成为链的时候右端点在左端点的右边w[i].r += m;}sort(w + 1, w + n + 1); // 根据左端点进行排序n2 = n * 2;i = n + 1;for (i; i <= n2; i++)//复制一份{w[i].i1 = w[i - n].i1;w[i].l = w[i - n].l + m;w[i].r = w[i - n].r + m;}
}void st()
{int o = 1;for (int i = 1; i <= n2; ++i){while (o <= n2 && w[o].l <= w[i].r)o++;a[i][0] = o - 1; // 找到左端点小于当前i的右端点且右端点最远的点}for (int i = 1; (1 << i) <= n; ++i) // i相当于从s点走了2的i次{for (int s = 1; s <= n2; ++s){a[s][i] = a[a[s][i - 1]][i - 1]; // 公式}}
}
void solve(int x)
{int len = w[x].l + m, now = x, ans = 1;//len就是计划点for (int i = 20; i >= 0; --i){int to = a[now][i];//如果当前点走2的i次方步存在最优点,那下一个i判断的就是从当前最优点开始走2的i次方步能否到达下一个最优点,一直到计划点if (to && w[to].r < len){ans = ans + (1 << i);now = to;}}res[w[x].i1] = ans + 1;//只能加上最后一个点,如果加其他数那都证明for循环每盘玩,因为if的判断条件是小于计划点
}
int main()
{init();st();for (int i = 1; i <= n; ++i){solve(i);}for (int i = 1; i <= n; ++i){cout << res[i] << " \n"[i == n];}return 0;
}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/74810.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

前后端实现双Token无感刷新用户认证

前后端实现双Token无感刷新用户认证 本文记录了使用双Token机制实现用户认证的具体步骤,前端使用的Vue,后端使用SpringSecurity和JWT 双Token分别指的是AccessToken和RefreshToken AccessToken:每次请求需要携带AccessToken访问后端数据,有效期短,减少AccessToken泄露带来…

门罗币隐私保护之环签名

主页微信公众号:密码应用技术实战 博客园首页:https://www.cnblogs.com/informatics/ GIT地址:https://github.com/warm3snow简介 在《门罗币隐私保护之隐形地址》文章中,我们重点介绍了门罗币Monero的隐形地址技术,门罗币通过隐形地址保证了交易的不可链接性,并实现了用…

Maven的学习

Maven 安装与配置 今天我们来学习一下Maven,Maven就相当于一个管理的工具,原理就是使用一个插件,这个插件由多个jar包构成。 在一个公司的项目开发过程中,一个大的项目通常被分为好几个小的模块,由不同的人去完成,但是不同的人在开发的过程中,使用的组件,jar包难免会有…

jdk8中文文档及安卓阅读器

例:下载链接: 文档(密码:76nh) 软件(密码:5wrj) 原文链接: http://466dd.com

7-1计算阶乘和【PTA嵌套循环程序设计】

嵌套循环程序设计 7-1计算阶乘和#include<stdio.h>int f(int a){int sum = 1;for(int i=1;i<=a;i++){sum *= i;}return sum;}//构造N!函数int main(){int N = 0,sum = 0;//初始化scanf("%d",&N);if(N>1){for(int i=1;i<=N;i++){sum += f(i);//实…

从认识 Kubernetes 开始

你也说,我也说,那什么是 K8s 呢?Author: ACatSmiling Since: 2024-10-21认识 Kubernetes 什么是 Kubernetes 官方网站:https://kubernetes.io Kubernetes,是 Google 严格保密十几年的秘密武器 Borg 系统的一个开源版本,于 2014 年 9 月发布第一个版本,2015 年 7 月发布第…

java的三大程序结构

JAVA的三大程序结构 一:顺序结构 程序走上执行到下。 二:选择结构 if单选择结构 if(布尔表达式){ //如果布尔表达式的值为ture则执行{}里的语句块 } public class IfDemo01 {public static void main(String[] args) {//接收键盘输入Scanner scanner = new Scanner(System.…

CSP模拟赛 #42

#40 懒得写了,#41 题目质量过低。A 有 \(n\) 张长度为 \(m\) 的纸条,每张纸条有 \(k_i\) 个位置有小写字母,其他位置透明。你需要合理从上到下排列这些纸条,使得最终在上方看到的字符串为 \(s\),保证对于每个位置,至少一张纸条在该位置有一个字母。给出方案或无解。 \(1\…