首页 > 其他分享 >蒲公英(Loj 分块模板9)

蒲公英(Loj 分块模板9)

时间:2023-05-18 12:13:02浏览次数:49  
标签:le 分块 Loj int ch Mode barrel 蒲公英 模板

[Violet]蒲公英

题目背景

亲爱的哥哥:

你在那个城市里面过得好吗?

我在家里面最近很开心呢。昨天晚上奶奶给我讲了那个叫「绝望」的大坏蛋的故事的说!它把人们的房子和田地搞坏,还有好多小朋友也被它杀掉了。我觉得把那么可怕的怪物召唤出来的那个坏蛋也很坏呢。不过奶奶说他是很难受的时候才做出这样的事的……

最近村子里长出了一大片一大片的蒲公英。一刮风,这些蒲公英就能飘到好远的地方了呢。我觉得要是它们能飘到那个城市里面,让哥哥看看就好了呢!

哥哥你要快点回来哦!

爱你的妹妹 Violet

Azure 读完这封信之后微笑了一下。

“蒲公英吗……”

题目描述

在乡下的小路旁种着许多蒲公英,而我们的问题正是与这些蒲公英有关。

为了简化起见,我们把所有的蒲公英看成一个长度为 \(n\) 的序列 \(\{a_1,a_2..a_n\}\),其中 \(a_i\) 为一个正整数,表示第 \(i\) 棵蒲公英的种类编号。

而每次询问一个区间 \([l, r]\),你需要回答区间里出现次数最多的是哪种蒲公英,如果有若干种蒲公英出现次数相同,则输出种类编号最小的那个。

注意,你的算法必须是在线的

输入格式

第一行有两个整数,分别表示蒲公英的数量 \(n\) 和询问次数 \(m\)。

第二行有 \(n\) 个整数,第 \(i\) 个整数表示第 \(i\) 棵蒲公英的种类 \(a_i\)。

接下来 \(m\) 行,每行两个整数 \(l_0, r_0\),表示一次询问。输入是加密的,解密方法如下:

令上次询问的结果为 \(x\)(如果这是第一次询问,则 \(x = 0\)),设 \(l=((l_0+x-1)\bmod n) + 1,r=((r_0+x-1) \bmod n) + 1\)。如果 \(l > r\),则交换 \(l, r\)。
最终的询问区间为计算后的 \([l, r]\)。

输出格式

对于每次询问,输出一行一个整数表示答案。

样例 #1

样例输入 #1

6 3 
1 2 3 2 1 2 
1 5 
3 6 
1 5

样例输出 #1

1 
2 
1

提示

数据规模与约定

  • 对于 \(20\%\) 的数据,保证 \(n,m \le 3000\)。
  • 对于 \(100\%\) 的数据,保证 \(1\le n \le 40000\),\(1\le m \le 50000\),\(1\le a_i \le 10^9\),\(1 \leq l_0, r_0 \leq n\)。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>

using namespace std;

int n, m, block, cnt, ans, l, r;//block是块的长度,cnt是块的个数,ans是上一次询问的答案
int a[5211314], b[5211314], len;
int mode[521][1314], s[521][131400], pos[5211314];
//mode[i][j]表示从i到j的块中的众数,s[i][j]表示前i个块中出现j的次数
int barrel[5211314];


inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch > '9') {
		if (ch == '-') f = -1;
		ch = getchar(); 
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch - '0');
		ch = getchar();
	}
	return x * f;
}

void print(int x) {
	if (x < 0) x *= -1, putchar('-');
	if (x > 9) print(x / 10);
	putchar(x % 10 + '0');
	return;
}

void write(int x) {
	print(x);
	putchar('\n');
	return;
}

inline void Pretreatment() {
	sort(b + 1, b + 1 + n);
	len = unique(b + 1, b + 1 + n) - (b + 1);
	for (int i = 1; i <= n; ++ i) {
		a[i] = lower_bound(b + 1, b + 1 + len, a[i]) - b;
	}
	for (int i = 1; i <= cnt; ++ i) {
		for (int j = (i - 1) * block + 1; j <= min(i * block, n); ++ j) {
			//注意是j <= min(i * block, n)
			s[i][a[j]] ++;
		}
		for (int j = 1; j <= len; ++ j) {
			s[i][j] += s[i - 1][j];
		}
	}
	int maxn;
	for (int i = 1; i <= cnt; ++ i) {
		for (int j = i; j <= cnt; ++ j) {
			maxn = mode[i][j - 1];
			for (int k = (j - 1) * block + 1; k <= min(j * block, n); ++ k) {
				if ((s[j][a[k]] - s[i - 1][a[k]] > s[j][maxn] - s[i - 1][maxn]) || 
					(s[j][a[k]] - s[i - 1][a[k]] == s[j][maxn] - s[i - 1][maxn] && a[k] < maxn)) {
				    maxn = a[k];
				}
			}
			mode[i][j] = maxn;
		}
	}
}

int main() {
	n = read(), m = read();
	block = sqrt(n);
	for (int i = 1; i <= n; ++ i) {
		a[i] = b[i] = read();
		pos[i] = (i - 1) / block + 1;
		if (pos[i] != pos[i - 1]) cnt ++;
	}
	Pretreatment();
	for (int temp = 1; temp <= m; ++ temp) {
		int Mode = 0;
		l = read();
		r = read();
		l = ((l + ans - 1) % n) + 1;
		r = ((r + ans - 1) % n) + 1;
		if (l > r) swap(l, r);
		if (pos[r] - pos[l] <= 1) {
			for (int i = l; i <= r; ++ i) barrel[a[i]] ++;
			for (int i = l; i <= r; ++ i) {
				if ((barrel[a[i]] > barrel[Mode]) || 
					(barrel[a[i]] == barrel[Mode] && a[i] < Mode)) {
					Mode = a[i];		
				}
				//barrel[a[i]] = 0;
                //这里barrel[a[i]]=0不能写里面,不然barrel[Mode]为0,下面同理
			}
			for (int i = l; i <= r; ++ i) barrel[a[i]] = 0;
		}
		else {
			for (int i = l; i <= block * pos[l]; ++ i) {
				barrel[a[i]] ++;
			}
			for (int i = (pos[r] - 1) * block + 1; i <= r; ++ i) {
				barrel[a[i]] ++;
			}
			Mode = mode[pos[l] + 1][pos[r] - 1];
			for (int i = l, pre, now; i <= block * pos[l]; ++ i) {
				pre = barrel[a[i]] + (s[pos[r] - 1][a[i]] - s[pos[l]][a[i]]);
                //barrel[i]是两端不完全覆盖的块中a[i]出现的次数
                //s[pos[r] - 1][a[i]] - s[pos[l]][a[i]]则是完全覆盖的块中a[i]出现的次数
				now = barrel[Mode] + (s[pos[r] - 1][Mode] - s[pos[l]][Mode]);
				if ((pre > now) || (pre == now && a[i] < Mode)) Mode = a[i];
				//barrel[a[i]] = 0;
			}
			for (int i = (pos[r] - 1) * block + 1, pre, now; i <= r; ++ i) {
				pre = barrel[a[i]] + (s[pos[r] - 1][a[i]] - s[pos[l]][a[i]]);
				now = barrel[Mode] + (s[pos[r] - 1][Mode] - s[pos[l]][Mode]);
				if ((pre > now) || (pre == now && a[i] < Mode)) Mode = a[i];
				//barrel[a[i]] = 0;
			}
			for (int i = l, pre, now; i <= block * pos[l]; ++ i) barrel[a[i]] = 0;
			for (int i = (pos[r] - 1) * block + 1, pre, now; i <= r; ++ i) barrel[a[i]] = 0;
		}
		ans = b[Mode];
		write(ans);
	}
	return 0;
}

标签:le,分块,Loj,int,ch,Mode,barrel,蒲公英,模板
From: https://www.cnblogs.com/jueqingfeng/p/17411532.html

相关文章

  • Loj分块模板1
    #include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>usingnamespacestd;intn,m,len;intpos[5211314],add[5211314],num[5211314];inlinevoidAdd(intLiftPos,intRightPos,intval......
  • Midjourney|文心一格prompt教程[Text Prompt(下篇)]:游戏、实物、人物、风景、动漫、邮票
    Midjourney|文心一格prompt教程[TextPrompt(下篇)]:游戏、实物、人物、风景、动漫、邮票、海报等生成,终极模板教学场景6:游戏Prompt真的越长越好吗?按照Midjourney的官方文档里的说法,并不一定:Promptscanbeverysimple.Singlewords(orevenanemoji!)willproducean......
  • 模板模式(Template Pattern)
    模板模式一、介绍  模板模式(TemplatePattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方式使......
  • SIEMENS/西门子西门子1200plc轴运动控制程序模板 介绍:此
    SIEMENS/西门子西门子1200plc轴运动控制程序模板介绍:此程序是之前给海康威视做的一台装路由器壳子的机器。程序有以下:1):调用轴控制块做的控制3个伺服,2):1个电缸,3):用PUTGET块与上下游plc通讯,4):轴控制块5):气缸报警块6):完整的电路图7):威纶通触摸屏程序8):IO表程序块已经在很多个项......
  • opencv模板匹配
    opencv模板匹配  读取图像并转换为灰度图像。 importcv2#读取图像img=cv2.imread('template.jpg')#转换为灰度图像gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 检测关键点并绘制矩形框。 #使用SIFT算法检测关键点......
  • 【BZOJ4241】【回滚莫队模板题】历史研究
    Description给定一个序列,每次询问区间[l,r][l,r]内,所有权值与其出现次数的乘积的最大值。Solution回滚莫队模板题。将询问以左端点所在块为第一关键字,右端点为第......
  • 【CF1012E】【LOJ2818】Cycle Sort(并查集)
    Description给定一个⻓为nn的数列,你可以多次进行如下操作:选定kk个不同的下标i1,i2…iki1,i2......
  • 企业级项目模板的配置与集成(Vite + Vue3 + TypeScript)
    企业级项目模板的配置与集成(Vite+Vue3+TypeScript)1、项目介绍项目使用:eslint+stylelint+prettier来对我们代码质量做检测和修复。需要使用husky来做commit拦截需要使用commitlint来统一提交规范需要使用preinstall来统一包管理工具。2、环境准备nodev16.14.2pnp......
  • P3919 【模板】可持久化线段树 1(可持久化数组) 题解
    一、题目描述:维护这样的一个长度为$n$的数组,支持以下两种操作$1$:在某个历史版本上修改某一个位置上的值$2$:访问某个历史版本上的某一位置的值每进行一次操作,就会生成一个新的版本(对于操作2,生成的就是一个完全一样的版本)。版本编号即为当前操作......
  • 离散化模板
    https://www.acwing.com/problem/content/description/804/#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>#include<vector>usingnamespacestd;typedefpair<int,int>PII;constintN=300010;/......