luogu P4135 作诗
郑重声明:我的前几到分块题写法上都有点小毛病,以这篇为主!
这道题感觉也是分块的基本套路,只不过卡常,得开氧气。
维护俩:sum[i][j]表示前 i 块中,数字 j 出现了多少次,ans[i][j]表示块 i 到块 j 的答案。这两者都可以在O(n√n)内预处理。方法也比较套路,具体看代码。
查询的时候也很套路,多开一个num[i],表示 i 这个数在零散部分出现了多少次,那么num[i] + sum[r - 1][i] - sum[l][i]就是在[L, R]中出现了多少次。
因为卡常,所以别用memset,开一个数组记录存了那些数,然后逐个清零即可。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-;
const int maxn = 1e5 + ;
const int maxb = ;
inline ll read()
{
ll ans = ;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) {last = ch; ch = getchar();}
while(isdigit(ch)) {ans = (ans << ) + (ans << ) + ch - ''; ch = getchar();}
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < ) x = -x, putchar('-');
if(x >= ) write(x / );
putchar(x % + '');
} int n, c, m, a[maxn];
int S, Cnt = , blo[maxn], lb[maxb], rb[maxb];
int sum[maxb][maxn], ans[maxb][maxb];
int num[maxn], cnt[maxn], cn = ;
void init()
{
S = sqrt(n);
Cnt = n % S ? n / S + : n / S;
for(int i = ; i <= Cnt; ++i) lb[i] = rb[i - ] + , rb[i] = lb[i] + S - ; //这里以前的写法不对
rb[Cnt] = n;
for(int i = , j = ; i <= n; ++i) blo[i] = j, j += (i == rb[j]);
for(int i = ; i <= Cnt; ++i)
{
for(int j = ; j <= c; ++j) sum[i][j] += sum[i - ][j];
for(int j = lb[i]; j <= rb[i]; ++j) sum[i][a[j]]++;
}
for(int i = ; i <= Cnt; ++i)
{
int tot = ;
for(int j = lb[i], k = i; j <= n; ++j)
{
if(!num[a[j]]) cnt[++cn] = a[j];
if(++num[a[j]] > )
{
if(num[a[j]] & ) tot--;
else tot++;
}
if(j == rb[k]) ans[i][k++] = tot;
}
while(cn) num[cnt[cn]] = , cn--;
}
}
int query(int L, int R)
{
int l = blo[L], r = blo[R], ret = ;
if(l == r)
{
for(int i = L; i <= R; ++i)
{
if(!num[a[i]]) cnt[++cn] = a[i];
if(++num[a[i]] > )
{
if(num[a[i]] & ) ret--;
else ret++;
}
}
while(cn) num[cnt[cn]] = , cn--;
return ret;
}
ret = ans[l + ][r - ];
for(int i = L; i <= rb[l]; ++i)
{
if(!num[a[i]]) cnt[++cn] = a[i];
num[a[i]]++;
int tp = num[a[i]] + sum[r - ][a[i]] - sum[l][a[i]];
if(tp > )
{
if(tp & ) ret--;
else ret++;
}
}
for(int i = lb[r]; i <= R; ++i)
{
if(!num[a[i]]) cnt[++cn] = a[i];
num[a[i]]++;
int tp = num[a[i]] + sum[r - ][a[i]] - sum[l][a[i]];
if(tp > )
{
if(tp & ) ret--;
else ret++;
}
}
while(cn) num[cnt[cn]] = , cn--;
return ret;
} int Ans = ; int main()
{
n = read(), c = read(), m = read();
for(int i = ; i <= n; ++i) a[i] = read();
init();
for(int i = ; i <= m; ++i)
{
int L = read(), R = read();
L = (L + Ans) % n + ; R = (R + Ans) % n + ; if(L > R) swap(L, R);
Ans = query(L, R);
write(Ans), enter;
}
return ;
}
luogu P4135 作诗的更多相关文章
- 洛谷P4135 作诗 (分块)
洛谷P4135 作诗 题目描述 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章 ...
- [Luogu 4135] 作诗
Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M ...
- P4135 作诗——分块
题目:https://www.luogu.org/problemnew/show/P4135 分块大法: 块之间记录答案,每一块记录次数前缀和: 注意每次把桶中需要用到位置赋值就好了: 为什么加了特判 ...
- 洛谷P4135 作诗
题意:[l,r]之间有多少个数出现了正偶数次.强制在线. 解:第一眼想到莫队,然后发现强制在线...分块吧. 有个很朴素的想法就是蒲公英那题的套路,做每块前缀和的桶. 然后发现这题空间128M,数组大 ...
- P4135 作诗
传送门 分块 设sum[ i ] [ j ] 存从左边到第 i 块时,数字 j 的出现次数 f [ i ] [ j ] 存从第 i 块,到第 j 块的一整段的答案 那么最后答案就是一段区间中几块整段的 ...
- 洛谷 P4135 作诗
分块大暴力,跟区间众数基本一样 #pragma GCC optimize(3) #include<cstdio> #include<algorithm> #include< ...
- 【分块】P4135 作诗
分块太暴力惹... 没做出来.看了题解qaq 分析: 两头$\sqrt{n}$暴力维护 预处理ans[i][j],sum[i][j] sum[i][j]是一个前缀和,前i块值为j的数量 ans[i][ ...
- 洛谷 P4135 作诗(分块)
题目链接 题意:\(n\) 个数,每个数都在 \([1,c]\) 中,\(m\) 次询问,每次问在 \([l,r]\) 中有多少个数出现偶数次.强制在线. \(1 \leq n,m,c \leq 10 ...
- 洛谷P4135 作诗(不一样的分块)
题面 给定一个长度为 n n n 的整数序列 A A A ,序列中每个数在 [ 1 , c ] [1,c] [1,c] 范围内.有 m m m 次询问,每次询问查询一个区间 [ l , r ] [l, ...
随机推荐
- jstl缺包时的报错
jsp中:<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 报错: ...
- angular 与 layer 集成过程
layer 的提示框和弹层确实也好用,在使用angular的前提下,使用layer遇到诸多麻烦,记录下来. 在类型是1页面层,主要问题在遮罩方面,造成无法编辑. 开始:引入layer 样式,angul ...
- TSM简介
转自:https://www.cnblogs.com/Study-Blog/p/8644376.html Tivoli TSM产品功能详述Tivoli TSM(Tivoli Storage Manag ...
- windows 下配置ndk环境,无需cygwin
时隔好久要用ndk编译jni库,本以为配制安装cygwin环境,便按部就班的下载安装,但是公司的网速真的不给力,三天安装了三四次都没有安装成功(我选择的是在线安装),于是我便开始查ndk的官网看看,发 ...
- Java如何实现form表单提交的数据自动对应实体类(源码)
原文出自:https://blog.csdn.net/seesun2012 原生Java+JQuery form表单serializeArray提交自动对应java实体,这是一个实际的例子: html ...
- javaweb之jsp指令
1.JSP指令简介 JSP指令是为JSP引擎设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令:page指令,Include指 ...
- 监听css3的animation动画和transition事件
webkit-animation动画有三个事件: 开始事件: webkitAnimationStart 结束事件: webkitAnimationEnd 重复运动事件: webkitAnimation ...
- float、display和流
一.css的元素有很深的道理和它存在的意义 块元素:默认元素的上下左右会有间隔(即使设置margin.padding为0也一样).如果想0间隔,考虑float. float:会使元素自动生成一个块级框 ...
- Hibernate 注解(Annotations 一)
1. @Entity 将一个类声明为一个实体bean(即一个持久化POJO类). 2. @Table 声明了该实体bean映射指定的表(table),目录(catalog)和schema名字 3. @ ...
- 解决方案看起来是受源代码管理,但无法找到它的绑定信息。保存解决方案的源代码管理设置的MSSCCPRJ.SCC文件或其他项可能己被删除。
Visual Studio 2015 + SVN 开发环境,今天打开项目,就报了下面这个错误,先前是好好的! 解决方案看起来是受源代码管理,但无法找到它的绑定信息.保存解决方案的源代码管理设置的MSS ...