题意

不带修改,查询数列[1,n]中[l,r]内的出现正偶数次的数的个数, 数列中的数 <= 1e5, n <= 1e5, 强制在线

算法

​ 查询的内容: 区间内出现正偶数次的数的个数.
这个内容不具有可合并性, 像区间众数一样…. (知道[l,mid]和[mid+1,r]中 的答案, 不能知道[l,r]中的答案)

​ 主席树没有想法….看来只能暴力了???

​ 对!! 我们可以写一个O(nn−−√)O(nn)的暴力—分块!!!

​ 具体说, 我们可以先暴力 开个桶 预处理每两块中间的答案, 复杂度 O(nn−−√)O(nn)

​ (当然不能把桶扫一遍啦…因为每次指针移动桶内计数器只改变1, 所以我们可以根据前一块的答案 略加修改 得出后一块的答案….这个在大佬看来就是暴力?? 但是我没有想到)

​ 对于块外的情况, 我们只需统计块外数对块内的影响. 由于块外数字最多只有2n−−√2n 个, 所以我们只需要知道块内数字出现的次数(通过前缀和得到), 然后开桶暴力统计块外数字即可算出影响.

经验总结

​ 这道题出题人真毒瘤, 卡掉了O(nn−−√log(n))O(nnlog(n))的算法, 只让O(nn−−√)O(nn)的算法过.

​ 一开始, 我查询时开桶扫描, 但是每次都把桶清空一遍….TLE了

​ 之后 , 我放弃了 开桶, 改为排序后统计次数.. 被卡了

​ 但是我没想到一点… 将桶初始化时不要memset啊…只需要把这2n−−√2n个数在桶内位置清零就好了…这样我才写出了正解….

​ 最后 , 这道题卡内存, 但是BZOJ 会把MLE 显示为TLE….太坑了….

代码

#include<bits/stdc++.h>
using namespace std; int read(){int f = 1; char c = getchar();int ans = 0;while(!isdigit(c)){if(c == '-')f = -1;c = getchar();}while( isdigit(c)){ans = ans*10 + c - '0';c = getchar();}ans *= f; return ans;}
//templates const int maxn = 100005, mxsiz = 265;
int f[mxsiz][mxsiz], g[mxsiz][maxn];
int a[maxn], n, q, c, sizB, cntB;
int bl[maxn], st[maxn], ed[maxn];
int bucket[maxn]; void precalc(int curB){
for(int i = 1; i <= c; i++) g[curB][i] = g[curB - 1][i];
for(int i = curB*sizB - sizB + 1; i <= min(curB*sizB, n); i++){
//if(curB == 317)printf("%d\n", a[i]);
g[curB][ a[i] ]++;
} memset(bucket, 0, sizeof bucket);
int ans = 0;
for(int i = curB*sizB - sizB + 1; i <= n; i++){
bucket[a[i]]++;
if(bucket[a[i]] != 1){
ans += (bucket[ a[i] ] & 1) ? -1 : 1;
} if(ed[ i ] == i) f[curB][ bl[i] ] = ans;
}
} void init(){
n = read(), c = read(), q = read();
for(int i = 1; i <= n; i++)
a[i] = read();
cntB = pow(n, 0.5), cntB = min(cntB, 255);
if(n % cntB == 0) sizB = n/cntB;
else sizB = n / cntB + 1;
for(int i = 1; i <= n; i++) bl[i] = (i-1) / sizB + 1;
for(int i = 1; i <= n; i++) st[i] = (bl[i] - 1)*sizB + 1, ed[i] = min(bl[i]*sizB, n); for(int i = 1; i <= cntB; i++) precalc(i);
} void solve(){
int ans = 0;
while(q--){
int l = read(), r = read();
l = (l + ans)%n + 1, r = (r+ans)%n+1;
if(l > r) swap(l, r); ans = 0;
if(r - l <= 2*sizB){
for(int i = l; i <= r; i++) bucket[ a[i] ] = 0;
for(int i = l; i <= r; i++){
bucket[a[i]]++;
if(bucket[a[i]] != 1)
ans += (bucket[ a[i] ] & 1) ? -1 : 1;
} printf("%d\n", ans);
} else {
int lbl = bl[l], rbl = bl[r];
if(l != st[l]) lbl++;
if(r != ed[r]) rbl--;
for(int i = l; i < lbl*sizB - sizB + 1; i++) bucket[a[i]] = g[rbl][a[i] ] - g[lbl -1][a[i] ];
for(int i = rbl*sizB + 1; i <= r; i++) bucket[a[i]] = g[rbl][a[i] ] - g[lbl -1][a[i] ]; ans = f[lbl][rbl]; for(int i = l; i < lbl*sizB - sizB + 1; i++) {
bucket[a[i]]++;
if(bucket[a[i]] != 1)
ans += (bucket[ a[i] ] & 1) ? -1 : 1;
}
for(int i = rbl*sizB + 1; i <= r; i++) {
bucket[a[i]]++;
if(bucket[a[i]] != 1)
ans += (bucket[ a[i] ] & 1) ? -1 : 1;
} printf("%d\n", ans);
} }
}
signed main(){ init();
solve(); return 0;
}

BZOJ2821 作诗(Poetize) 分块的更多相关文章

  1. BZOJ2821 作诗(Poetize) 【分块】

    BZOJ2821 作诗(Poetize) Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI ...

  2. 【分块】BZOJ2821 作诗(Poetize)

    2821: 作诗(Poetize) Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 3265  Solved: 951[Submit][Status][ ...

  3. BZOJ 2821: 作诗(Poetize)( 分块 )

    分块,分成N^0.5块.O(N^1.5)预处理出sm[i][j]表示前i块中j的出现次数, ans[i][j]表示第i~j块的答案. 然后就可以O(N^0.5)回答询问了.总复杂度O((N+Q)N^0 ...

  4. 【BZOJ2821】作诗(Poetize) 分块

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

  5. 2018.09.30 bzoj2821: 作诗(Poetize)(分块)

    传送门 分块经典题目. 先将数列分块. 然后预处理出每两个块之间有多少个数出现了正偶数次. 这样查询的时候对于中间的完整块直接用预处理出的数组搞定. 剩下的暴力枚举求解. 代码: #include&l ...

  6. BZOJ2821 作诗(Poetize) 主席树 bitset

    原文链接https://www.lydsy.com/JudgeOnline/problem.php?id=2821 题目传送门 - BZOJ2821 题意 $n$ 个数,$m$ 组询问,每次问 $[l ...

  7. bzoj2821: 作诗(Poetize)

    分块 分sqrt(n)块 F[i][j]表示块i到块j的答案 s[i][j]表示数字i在前j块内出现了几次 #include <iostream> #include <cstdio& ...

  8. BZOJ2821 作诗(分块)

    和区间众数几乎一模一样的套路. // luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include&l ...

  9. BZOJ 2821作诗(Poetize) 分块

    Description 有一个长度为n的序列,序列每个元素的范围[1,c],有m个询问x y,表示区间[x,y]中出现正偶数次的数的种类数. Solution 大力分块解决问题. 把序列分块,f[i] ...

随机推荐

  1. 《剑指offer》二叉搜索树的后序遍历序列

    本题来自<剑指offer> 二叉搜索树的后序遍历序列 题目: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字 ...

  2. Client-Side Attacks

    1.之前看到中间人攻击方式,要使用ssl服务构架一个劫持会话,使得攻击者和被攻击者客户端连接.ssl 服务(secure Socket Layer安全套接) ,以及后续出现的TSL(Transport ...

  3. requests中get和post传参

    get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...

  4. springboot动态多数据源切换

    application-test.properties #datasource -- mysql multiple.datasource.master.url=jdbc:mysql://localho ...

  5. 一脸懵逼学习Struts数据校验以及数据回显,模型驱动,防止表单重复提交的应用。

    1:Struts2表单数据校验: (1)前台校验,也称之为客户端校验,主要是通过Javascript编程的方式进行数据的验证. (2)后台校验,也称之为服务器校验,这里指的是使用Struts2通过xm ...

  6. bzoj 2832

    题解: 首先有一个比较显然的事情是如果我们确定了买的次数这道题就可以简单的贪心了 但是答案和买的次数是什么关系呢.. 好像是可以三分的 所以应该是单峰的 这里用了模拟退火,而且是没有处理失败情况的模拟 ...

  7. [转]简单三步,用 Python 发邮件

    https://zhuanlan.zhihu.com/p/24180606 0. 前言 发送电子邮件是个很常见的开发需求.比如你写了个监控天气的脚本,发现第二天要下雨,或者网站上关注的某个商品降价了, ...

  8. 基于nopcommerce b2c开源项目的精简版开发框架Nop.Framework

    http://www.17ky.net/soft/70612.html?v=1#0-sqq-1-39009-9737f6f9e09dfaf5d3fd14d775bfee85 项目详细介绍 该开源项目是 ...

  9. JMeter实现登录初始化(类似LR的init函数功能实现)

    1.项目背景 在做项目的性能测试过程中,发现系统的登录功能非常慢,所以,在涉及到登录才能操作的场景,尽量避开登录操作 解决方案: 首选设置“登录并生成签名值”线程组

  10. nethogs命令执行报异常的解决方法