题解【UVA12003】Array Transformer
题目描述
输入输出格式
输入格式
输出格式
输入输出样例
输入样例#1
10 1 11
1
2
3
4
5
6
7
8
9
10
2 8 6 10
输出样例#1
1
2
3
4
5
6
7
8
9
6
题意简述
输入一个数组\(a[1,...,n]\)和\(m\)条指令,你的任务是对数组进行变换,输出最终结果。
每条指令形如\((L,R,v,p)\),表示先统计出\(a[L],a[L+1],...,a[R]\)中严格小于\(v\)的元素个数\(k\),然后把\(a[p]\)修改成\(u \times k / (R-L+1)\)。这里的除法为整数除法(即忽略小数部分)。
【输入格式】
输入的第一行为\(3\)个整数\(n,m,u(1 \leq n \leq 300 000,1 \leq m \leq 50000 1 \leq u \leq 10^9)\)。
以下\(n\)行为数组\(a[i](1 \leq a[i] \leq u)\)。
再以下\(m\)行每行为\(4\)个整数\(L,R,v,p(1 \leq L \leq R \leq n,1 \leq v \leq u,1 \leq p \leq n)\)。
【输出格式】
输出\(n\)行,每行为一个整数,即变换后的最终数组。
题解
我们可以使用分块法来解决此题。
预设一个整数值\(SIZE\),然后每\(SIZE\)个元素分成一块,分别排好序,则查询\((L,R,v,p)\)的执行可以分成两步。
第一步,先找出\(L\)和\(R\)所在的块,逐一比较出有多少个元素比\(v\)小,然后对于中间的块直接用二分查找,相加后得到\(k\)。
第二步,在\(p\)所在块中找到修改前的\(a[p]\),改成\(u \times k/(R-L+1)\),然后不断交换相邻元素,直到这个块排好序。
根据常识,我们知道,\(SIZE\)的大小在\(\sqrt{n}\)左右比较快,也可以实验得出比较好的\(SIZE\)值。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
using namespace std;
inline int gi()
{
int f = 1, x = 0;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return f * x;
}
const int MAXN = 300000 + 5, SIZE = 4096;//SIZE为块的大小
int a[MAXN], r, block[MAXN / SIZE + 1][SIZE], n, m, u, v;
inline void init()//输入+预处理
{
n = gi(), m = gi(), u = gi();
int b = 0, w = 0;
for (int i = 0; i < n; i++)
{
a[i] = gi();//输入每个数
block[b][w] = a[i];//a[i]为第b个块的第w个元素
if (++w == SIZE)//这个块是完整的
{
++b;//进入下一个块
w = 0;
}
}
for (int i = 0; i < b; i++)
{
sort(block[i], block[i] + SIZE);//将完整的块排好序
}
if (w)
{
sort(block[b], block[b] + w);//将边缘块排好序
}
}
inline int getans(int l, int r, int p)//求出区间内小于v的数的个数
{
int lft = l / SIZE, rht = r / SIZE, f = 0;
if (lft == rht)//如果l和r在同一块内
{
for (int i = l; i <= r; i++)//直接暴力判断即可
{
if (a[i] < v)
{
++f;
}
}
return f;//返回个数
}
for (int i = l; i < (lft + 1) * SIZE; i++)//第一块
{
if (a[i] < v)
{
++f;
}
}
for (int i = rht * SIZE; i <= r; i++)//最后一块
{
if (a[i] < v)
{
++f;
}
}
for (int i = lft + 1; i < rht; i++)//中间块
{
f = f + lower_bound(block[i], block[i] + SIZE, v) - block[i];//二分查找
}
return f;//返回个数
}
inline void modify(int x, int y)//进行修改
{
if (a[x] == y)//如果要修改的值就是当前值
{
return;//就不用修改,直接返回
}
int o = a[x], q = 0, *g = &block[x / SIZE][0];//g就是x所在的块
a[x] = y;//修改值
while (g[q] < o)
{
++q;//找到y在块中的位置
}
g[q] = y;//进行修改
if (y > o)//y太大,往后交换
{
while (q < SIZE - 1 && g[q] > g[q + 1])
{
swap(g[q], g[q + 1]);
++q;
}
}
else//x太小,往前交换
{
while (q > 0 && g[q] < g[q - 1])
{
swap(g[q], g[q - 1]);
--q;
}
}
}
int main()
{
init();
while (m--)
{
int L, R, p;
L = gi(), R = gi(), v = gi(), p = gi();
--L, --R, --p;
int z = getans(L, R, v);//求出区间内比v小的数
modify(p, (long long)u * z / (R - L + 1));//进行修改
}
for (int i = 0; i < n; i++)
{
printf("%d\n", a[i]);//输出每个数
}
return 0;//结束
}
题解【UVA12003】Array Transformer的更多相关文章
- UVA 12003 Array Transformer
Array Transformer Time Limit: 5000ms Memory Limit: 131072KB This problem will be judged on UVA. Orig ...
- Array Transformer UVA - 12003
题目:传送门 题意: 给你n个数,要进行m次操作 对于每次操作(l,r,v,p)代表:在区间[l,r]中有x(这个x是需要你自己找出来的)个数小于v,你需要把序列的第p个位置的值改成u∗k/(r−l ...
- uva 12003 Array Transformer (大规模阵列)
白皮书393页面. 乱搞了原始数组中.其实用另一种阵列块记录. 你不能改变原始数组. 请注意,与原来的阵列和阵列块的良好关系,稍微细心处理边境.这是不难. #include <cstdio> ...
- UVa 12003 Array Transformer (分块)
题意:给定一个序列,然后有 m 个修改,问你最后的序列是什么,修改是这样的 l r v p 先算出从 l 到 r 这个区间内的 小于 v 的个数k,然后把第 p 个的值改成 k * u / (r - ...
- leetCode题解之Array Partition I
1.题目描述 2.分析 按照题目要求,主要就是对数组进行排序 3.代码 int arrayPairSum(vector<int>& nums) { ; sort( nums.beg ...
- uva 12003 Array Transformer (线段树套平衡树)
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- 算法与数据结构基础 - 数组(Array)
数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...
- Spark Mllib框架1
1. 概述 1.1 功能 MLlib是Spark的机器学习(machine learing)库,其目标是使得机器学习的使用更加方便和简单,其具有如下功能: ML算法:常用的学习算法,包括分类.回归.聚 ...
- Spark MLlib框架详解
1. 概述 1.1 功能 MLlib是Spark的机器学习(machine learing)库,其目标是使得机器学习的使用更加方便和简单,其具有如下功能: ML算法:常用的学习算法,包括分类.回归.聚 ...
随机推荐
- 第31届IMO 第2题
题目 设n>=3,考虑一个圆上由2n-1个不同点构成的集合E.现给E中恰好k个点染上黑色,如果至少有一对黑点使得这两个黑点之间的弧上(两段弧中的某一个)包含恰好E中的n个点,就成这样的染色方法是 ...
- dos命令获取系统时间与变量定义
1.获取系统时间及格式化 参考文章: 1.1 cmd下获取系统时间 1.2 获取系统时间的DOS命令 2.变量定义 https://www.jb51.net/article/49197.htm 3.使 ...
- Docker最全教程——从理论到实战(二十二)
前言 最近正在抽时间编写k8s的相关教程,很是费时,等相关内容初步完成后,再和大家分享.对于k8s,还是上云更为简单.稳定并且节省成本,因此我们需要对主流云服务的容器服务进行了解,以便更好地应用于生产 ...
- 假期学习【九】首都之窗百姓信件爬取代码优化以及处理 2020.2.7 Python
今天对爬取程序进行了优化,修正了错误. 遇到了两个问题与错误: 1.忘记了对文件的读写设置格式,导致导入Hive数据库无法正常显示以及写入. 2.文件的读写操作有误导致数据量仅有应该有的1/2 不完整 ...
- eclipse中配置maven环境
一.配置setting.xml文件 1.首先将下载好的maven打开,打开文件夹,首先就需要对maven安装目录下有个config文件夹,在文件夹下有settings.xml文件.settings里面 ...
- wx: wx.showModal 回调函数中调用自定义方法
一.在回调函数中调用自定义方法: 回调函数中不能直接使用this,需要在外面定义 var that = this 然后 that.自定义的方法.如下: //删除 onDelete: function ...
- Selenium3+python自动化013-操作浏览器的Cookie
为什么要用Cookie?在测试多个页面时候可绕过验证码输入,直接添加cookie,也可以在添加唯一标识时候使用. 一.操作浏览器的Cookie 1.1.验证码的处理方式 说明:WebDriver类库中 ...
- Java基础--数组(Arrays)
数组(Array),是多个相同类型数据按一定顺序排列 的集合,并使用一个名字命名,并通过编号的方式 对这些数据进行统一管理.本篇博客是对Java基础中的数组进行详细说明. 目录: 数组的概述 一维数组 ...
- 为什么 RMAN 控制文件自动备份的名称格式没有遵循 %F 规则
在 Oracle 中越是简单的问题,往往越难找到答案,举个例子: 你是否留意观察过在 RMAN 进行备份的时候,自动生成的控制文件名称是否是按照 %F 规则来生成的? 关于控制文件自动备份路径格式,在 ...
- 在电脑上用chrome浏览器调试android手机里的网页代码时,无法看到本地加载的js文件
在需要调试的js文件最顶部加上代码就可以看到了: console.log('haha'); debugger;