[洛谷]([Violet]蒲公英 - 洛谷)
[Acwing(数据较强)](249. 蒲公英 - AcWing题库)
“好诗意的题目啊......
那就用很诗意的代码写吧”
首先, 这题是给你 \(l, r\) 的限制目的是强制在线,所以莫队啥的不能用。
由于不满足“区间可加性”(已知\([l, r] \cup[r+1,k]\) 的众数,不能得出 \([l, k]\) 的众数), 所以树状数组/线段树就很难维护。
考虑分块,首先离散。 设块的长度为 \(T\) , 则有 \(n / T\) 块, 然后预处理第 \(i\) 到 \(j\) 块的众数以及数的出现次数, 这段时间复杂度 \(O(NT^2)\)。 之后两段暴力维护, \(O(N/T)\)
总的时间复杂度 \(O(NT^2 + MN/T)\)
所以如果 \(T=\sqrt{N}\) 时间复杂度就为 \(O(N\sqrt{N})\) ( \(N,M\) 同阶)
#include <bits/stdc++.h>
#define for_(i,a,b) for (int i = (a); i < (b); i++)
#define rep_(i,a,b) for (int i = (a); i <= (b); i++)
#define _Pos(i, j) (((i)-1)*cnt+(j))
using namespace std;
const int maxn = 4e5 + 10, mod = 1e9 + 7;// mod = 1949777;
const double EPS = 1e-3;
int n, m, t, cnt;
int a[maxn], id[maxn], l[maxn], r[maxn], b[maxn], s[maxn];
void solve() {
}
signed main() {
#ifdef LOCAL
freopen("w.in", "r", stdin);
freopen("w.ans", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
//
while (t * t * t < n)
t++;
t--; //
t = n / t; //the lenth of a bar
//
rep_(i, 1, n) {
cin >> a[i];
b[i] = a[i];
}
sort(b + 1, b + 1 + n);
int len = unique(b + 1, b + 1 + n) - b - 1;
rep_(i, 1, n) {
a[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
}
//
for (int i = 1; i <= n / t; i++) {
l[i] = (i - 1) * t + 1;
r[i] = i * t;
}
cnt = n / t;
if (r[cnt] < n) {
l[cnt + 1] = r[cnt] + 1;
r[cnt + 1] = n;
cnt++;
}
for (int i = 1; i <= cnt; i++) {
for (int j = l[i]; j <= r[i]; j++) {
id[j] = i;
}
}
vector<vector<int>> v(cnt * cnt + 1, vector<int>(n, 0));
//
for (int i = 1; i <= cnt; i++) {
for (int j = i; j <= cnt; j++) {
for (int k = l[i]; k <= r[j]; k++) {
v[_Pos(i, j)][a[k]]++;
}
int mx = 0, _S = 0;
for (int k = 1; k <= n; k++) {
if (mx < v[_Pos(i, j)][k] || mx == v[_Pos(i, j)][k] && _S > k) {
mx = v[_Pos(i, j)][k];
_S = k;
}
}
s[_Pos(i, j)] = _S;
}
}
//
vector<int> N(n + 1, 0);
int _X = 0;
for (int i = 1, L, R; i <= m; i++) {
cin >> L >> R;
L = (L + _X - 1) % n + 1, R = (R + _X - 1) % n + 1;
if (L > R)
swap(L, R);
int mx = 0, _S = 0;
if (id[L] == id[R]) {
for (int j = L; j <= R; j++) {
N[a[j]]++;
if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
mx = N[a[j]], _S = a[j];
}
} else {
// Left
for (int j = L; id[j] == id[L]; j++) {
N[a[j]]++;
if (N[a[j]] == 1) {
if (id[L] + 1 < id[R]) {
N[a[j]] += v[_Pos(id[L] + 1, id[R] - 1)][a[j]];
}
}
if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
mx = N[a[j]], _S = a[j];
}
// Right
for (int j = R; id[j] == id[R]; j--) {
N[a[j]]++;
if (N[a[j]] == 1) {
if (id[L] + 1 < id[R]) {
N[a[j]] += v[_Pos(id[L] + 1, id[R] - 1)][a[j]];
}
}
if (mx < N[a[j]] || mx == N[a[j]] && _S > a[j])
mx = N[a[j]], _S = a[j];
}
// Mid
if (id[L] + 1 < id[R] && N[s[_Pos(id[L] + 1, id[R] - 1)]] == 0) {
int _O = s[_Pos(id[L] + 1, id[R] - 1)];
int Tmp = v[_Pos(id[L] + 1, id[R] - 1)][_O];
if (mx < Tmp || mx == Tmp && _S > _O) {
mx = Tmp;
_S = _O;
}
}
}
_X = b[_S];
cout << _X << endl;
// clear
for (int j = L; id[j] == id[L]; j++)
N[a[j]] = 0;
for (int j = R; id[j] == id[R]; j--)
N[a[j]] = 0;
}
return 0;
}
总结:这里的基本问题是,我发现,您是否可以将代码块传递给Ruby数组,这实际上会将该数组的内容减少到另一个数组,而不是单个值(inject的方式)。最简洁的答案是不”。我接受这样的回答。感谢Squeegy提供了一个很好的循环策略来从数组中去除条纹。挑战:在不显式循环遍历数组的情况下减少数组的元素。输入:所有从-10到10(0除外)的整数随机排列。TheDesiredOutput:一个表示正数或负数条纹的数组。例如,-3表示三个连续的负数。2代表两个连续的正数。示例脚本:original_array=(-10..10).to_a.sort{rand(3)-1}original_array
这个问题在这里已经有了答案:HowtochunkanarrayinRuby(2个答案)关闭4年前。我有一个数组foo=%w(12345678910)如何将其拆分或“分块”为更小的数组?classArraydefchunk(size)#returnarrayofarraysendendfoo.chunk(3)#=>[[1,2,3],[4,5,6],[7,8,9],[10]]
我正在将分块数据从NodeJS应用程序发送回浏览器。这些block实际上是json字符串。我遇到的问题是每次调用onprogress函数时,它都会添加一个完整数据的字符串。这意味着第二个响应block附加到第一响应block,依此类推。我只想获得“刚刚”收到的数据block。代码如下:console.log("Startscan...");varxhr=newXMLHttpRequest();xhr.responseType="text";xhr.open("GET","/servers/scan",true);xhr.onprogress=function(){console.log
如何按元素对数组进行分块?例如lodash有这个函数按长度分块数组_.chunk(['a','b','c','d'],2);//=>[['a','b'],['c','d']]_.chunk(['a','b','c','d'],3);//=>[['a','b','c'],['d']]所以我有一个像这样的数组['a','b','*','c']我可以做类似的事情吗chunk(['a','b','*','c'],'*')这会给我[['a','b'],['c']]它类似于数组的字符串拆分 最佳答案 您可以使用array.Reduce:vara
我正在尝试从网络服务器(Node.js)下载HTML/JSON数据并在客户端将其转换为PDF。我希望在用户的浏览器上进行处理,这样我的服务器就不会因pdf转换而重载。如果数据不是那么大,应该没有问题。一份报告(从服务器下载的数据)可以加起来200、300MB,浏览器无法处理内存中的这么多数据。因此,我(可能)需要以block的形式下载和保存数据,或者将其直接通过管道传输到PDF转换器。但我无法理解它。我如何切片和存储/管道下载的数据?我一直在四处寻找并找到了几个库,但我仍然不知道如何让它们一起工作。有什么想法吗? 最佳答案 我认为让
我理解在webpack4上所做的伟大工作。特别是重写代码拆分插件。然而,由于它仍然有点新,我没有找到关于新SplitChunksPlugin的好文档。我对所选术语的含义感到困惑。例如:chunks:有3个可能的值“initial”、“async”和“all”。这是什么意思?初始block是条目?异步动态导入?都是初始+异步?如果我使用initial那么我的动态导入block将不会利用代码拆分?例如。main.tsx动态导入about.tsx,它正常导入lodash。Lodash不会被提取到vendor包中?enforce:我看到很多配置都设置了enforce:true,这是什么意思?为
我正在开发一个使用Node的项目,我们正在努力实现100%的功能覆盖。这是我们唯一没有测试过的函数,它在另一个函数中。varuserInput="";req.on("data",function(data){userInput+=data;});你如何着手测试这个功能?我们尝试从另一个文件导出函数,但没有成功。我应该提一下,我们正在使用磁带作为测试模块。 最佳答案 您需要根据请求触发此“数据”事件。这样这个回调就会被调用。例如,假设您的测试中有req,您可以做类似的事情(这是Mocha):req.trigger('data','sa
如何使用FetchAPI读取二进制分块响应。我正在使用以下代码,它可以从服务器读取分块响应。但是,数据似乎以某种方式被编码/解码,导致getFloat32有时会失败。我尝试使用curl读取响应,效果很好,这让我相信我需要做一些事情来让fetchapi将block视为二进制文件。响应的内容类型正确设置为“application/octet-stream”。constconsume=responseReader=>{returnresponseReader.read().then(result=>{if(result.done){return;}constdv=newDataView(re
我想我已经很接近这个了,我有以下dropzone配置:Dropzone.options.myDZ={chunking:true,chunkSize:500000,retryChunks:true,retryChunksLimit:3,chunksUploaded:function(file,done){done();}};但是由于done()命令,它在1个block后完成。我认为此时我需要检查是否所有block都已上传,如果已上传则调用done()这是分块的wiki:https://gitlab.com/meno/dropzone/wikis/faq#chunked-uploads这里
我正在构建一个开始变得相当大的网络应用程序(用es6编写的React应用程序)。结果,我发现我的JS文件在移动设备上的下载时间长得令人无法接受。我正在尝试将大型JS应用程序分块为按需加载的block。我正在使用webpack,并阅读了这篇文章:https://webpack.github.io/docs/code-splitting.html通过本文,我将我的代码拆分为app.js和vendor.js,其中vendor.js包含所有第三方模块/插件。我想更进一步,将app.js文件分解成几个入口点,然后根据需要下载block。上面的文章描述了如何使用CommonJS或AMD来做到这一点