题意:[l,r]之间有多少个数出现了正偶数次。强制在线。

解:第一眼想到莫队,然后发现强制在线...分块吧。

有个很朴素的想法就是蒲公英那题的套路,做每块前缀和的桶。

然后发现这题空间128M,数组大小我的是133M......看到有人卡到了122M,但是我又不想冒险,就换写法了。(题解里全是空间n1.5的...)

那就用蒲公英的另一个套路吧。。。vector + 二分。

预处理出每两个块之间的答案,然后查询的时候对边角扫一遍,每个数vector二分,求得出现几次,统计答案。

这样一来块大小是(n/logn)0.5的,然后交上去发现T成10分...自闭了。

YY出了个做法,每个数维护是第几个出现的该数值的数,然后发现对于某种数值只出现在一边边角的话,不会处理,又只会vector了...虽然还可以值域分块做到log(n0.5),但是感觉上没啥太大优化,懒得写了...

把之前的10分代码玄学调了一波块大小,然后吸氧,居然A了。。。。。。自闭了。

 // luogu-judger-enable-o2
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath> const int N = ; int bin[N], a[N], sum[][], n, lm, le[N], re[N], fr[N];
std::vector<int> v[N];
bool vis[N]; inline void read(int &x) {
x = ;
char c = getchar();
while(c < '' || c > '') {
c = getchar();
}
while(c >= '' && c <= '') {
x = (x << ) + (x << ) + c - ;
c = getchar();
}
return;
} inline int getTime(int x, int y, int c) {
if(x > y) {
return ;
}
x = std::lower_bound(v[c].begin(), v[c].end(), x) - v[c].begin();
y = std::upper_bound(v[c].begin(), v[c].end(), y) - v[c].begin() - ;
return y - x + ;
} inline int ask(int x, int y) {
int l = fr[x], r = fr[y], ans = ;
if(l == r) {
for(int k = x; k <= y; k++) {
if(bin[a[k]]) {
bin[a[k]] & ? ans++ : ans--;
}
bin[a[k]]++;
}
for(int k = x; k <= y; k++) {
bin[a[k]]--;
}
return ans;
}
for(int k = x; k <= re[l]; k++) {
bin[a[k]]++;
}
for(int k = le[r]; k <= y; k++) {
bin[a[k]]++;
}
for(int k = x; k <= re[l]; k++) {
if(vis[a[k]]) {
continue;
}
vis[a[k]] = ;
if(bin[a[k]] & ) {
int t = getTime(le[l + ], re[r - ], a[k]);
if(t) {
ans += t & ? : -;
}
}
else {
ans += getTime(le[l + ], re[r - ], a[k]) == ;
}
}
for(int k = le[r]; k <= y; k++) {
if(vis[a[k]]) {
continue;
}
vis[a[k]] = ;
if(bin[a[k]] & ) {
int t = getTime(le[l + ], re[r - ], a[k]);
if(t) {
ans += t & ? : -;
}
}
else {
ans += getTime(le[l + ], re[r - ], a[k]) == ;
}
}
for(int k = x; k <= re[l]; k++) {
vis[a[k]] = ;
bin[a[k]]--;
}
for(int k = le[r]; k <= y; k++) {
vis[a[k]] = ;
bin[a[k]]--;
}
return ans + sum[l + ][r - ];
} int main() {
int m;
read(n);
read(lm);
read(m);
int T = sqrt((double)(n) / log2(n) * );
for(int i = ; i <= n; i++) {
read(a[i]);
v[a[i]].push_back(i);
fr[i] = (i - ) / T + ;
}
// prework
for(int i = ; i <= fr[n]; i++) {
le[i] = re[i - ] + ;
re[i] = le[i] + T - ;
if(i == fr[n]) {
re[i] = n;
}
} for(int l = ; l <= fr[n]; l++) {
int ans = ;
for(int r = l; r <= fr[n]; r++) {
for(int k = le[r]; k <= re[r]; k++) {
if(bin[a[k]]) {
bin[a[k]] & ? ans++ : ans--;
}
bin[a[k]]++;
}
sum[l][r] = ans;
}
for(int k = le[l]; k <= n; k++) {
bin[a[k]]--;
}
} int lastans = ;
for(int i = , x, y; i <= m; i++) {
read(x);
read(y);
x = (x + lastans) % n + ;
y = (y + lastans) % n + ;
if(x > y) {
std::swap(x, y);
}
lastans = ask(x, y);
printf("%d\n", lastans);
} return ;
}

AC代码

udpate:其实可以删去只出现一次的数。不过恶意卡的话没啥优化效果。

洛谷P4135 作诗的更多相关文章

  1. 洛谷P4135 作诗 (分块)

    洛谷P4135 作诗 题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章 ...

  2. 洛谷 P4135 作诗 题解

    题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...

  3. 洛谷 P4135 作诗

    分块大暴力,跟区间众数基本一样 #pragma GCC optimize(3) #include<cstdio> #include<algorithm> #include< ...

  4. 洛谷 P4135 作诗(分块)

    题目链接 题意:\(n\) 个数,每个数都在 \([1,c]\) 中,\(m\) 次询问,每次问在 \([l,r]\) 中有多少个数出现偶数次.强制在线. \(1 \leq n,m,c \leq 10 ...

  5. 洛谷P4135 作诗(不一样的分块)

    题面 给定一个长度为 n n n 的整数序列 A A A ,序列中每个数在 [ 1 , c ] [1,c] [1,c] 范围内.有 m m m 次询问,每次询问查询一个区间 [ l , r ] [l, ...

  6. 洛谷P4135 Ynoi2016 掉进兔子洞 (带权bitset?/bitset优化莫队 模板) 题解

    题面. 看到这道题,我第一反应就是莫队. 我甚至也猜出了把所有询问的三个区间压到一起处理然后分别计算对应询问答案. 但是,这么复杂的贡献用什么东西存?难道要开一个数组 query_appear_tim ...

  7. P4135 作诗——分块

    题目:https://www.luogu.org/problemnew/show/P4135 分块大法: 块之间记录答案,每一块记录次数前缀和: 注意每次把桶中需要用到位置赋值就好了: 为什么加了特判 ...

  8. luogu P4135 作诗

    嘟嘟嘟 郑重声明:我的前几到分块题写法上都有点小毛病,以这篇为主! 这道题感觉也是分块的基本套路,只不过卡常,得开氧气. 维护俩:sum[i][j]表示前 i 块中,数字 j 出现了多少次,ans[i ...

  9. P4135 作诗

    传送门 分块 设sum[ i ] [ j ] 存从左边到第 i 块时,数字 j 的出现次数 f [ i ] [ j ] 存从第 i 块,到第 j 块的一整段的答案 那么最后答案就是一段区间中几块整段的 ...

随机推荐

  1. 20155209林虹宇Exp4 恶意代码分析

    Exp4 恶意代码分析 系统运行监控 使用schtasks指令监控系统运行 新建一个txt文件,然后将txt文件另存为一个bat格式文件 在bat格式文件里输入以下信息 然后使用管理员权限打开cmd, ...

  2. 字典学习(Dictionary Learning, KSVD)详解

    注:字典学习也是一种数据降维的方法,这里我用到SVD的知识,对SVD不太理解的地方,可以看看这篇博客:<SVD(奇异值分解)小结 >. 1.字典学习思想 字典学习的思想应该源来实际生活中的 ...

  3. Android开发——监听Android手机的网络状态

    0. 前言 在Android开发中监听手机的网络状态是一个常见的功能,比如在没网的状态下进行提醒并引导用户打开网络设置,或者在非wifi状态下开启无图模式等等.因此本篇将网上的资料进行了整理总结,方便 ...

  4. 洛咕 P4474 王者之剑

    宝石只能在偶数秒取到,假设有一个宝石在奇数秒取到了,那么上一秒是偶数秒,在上一秒的时候这里的宝石就没了. 相邻的两个宝石不能同时取,很显然,先取一块,那么这是偶数秒,取完了这一块之后相邻的都没了. 只 ...

  5. java maven项目迁移时缺失jar包 或者 maven jar包缺失时的解决方案

    这样弄完,jar包就都下载好了,就不缺失了. 从GitHub上checkout一个项目下来,导入idea后发现加载依赖奇慢无比,所以临时把网络调成FQ的代理,结果会发现idea会停止之前的下载,那怎么 ...

  6. CS100.1x-lab4_machine_learning_student

    这是这门课第一次接触机器学习,主题是Predicting Movie Ratings.难度比上一次作业要简单点..上一次作业真的挺难...相关ipynb文件见我github. 这里我们会用到Spark ...

  7. 微服务监控zipkin、skywalking以及日志ELK监控系列

    0.整体架构 整体架构目录:ASP.NET Core分布式项目实战-目录 一.目录 1.zipkin监控 2.skywalking监控 3.ELK日志监控 asp.net Core 交流群:78746 ...

  8. JavaScript快速入门-ECMAScript语句

    JavaScript语句(if.for.for in.do...while.while.break.continue.switch) 一.if语句 if (condition) statement1 ...

  9. LeetCode Letter Combinations of a Phone Number (DFS)

    题意 Given a digit string, return all possible letter combinations that the number could represent. A ...

  10. Linux Socket 编程简介

    在 TCP/IP 协议中,"IP地址 + TCP或UDP端口号" 可以唯一标识网络通讯中的一个进程,"IP地址+端口号" 就称为 socket.本文以一个简单的 ...