首页 > 其他分享 >P4688 [Ynoi2016] 掉进兔子洞

P4688 [Ynoi2016] 掉进兔子洞

时间:2023-12-05 17:35:17浏览次数:38  
标签:cur int 兔子 while Ynoi2016 array include Cpt P4688

题意

给定长度为 \(n\) 的序列 \(s\)。

有 \(m\) 个询问,每次询问三个区间,把三个区间中同时出现的数一个一个删掉,问最后三个区间剩下的数的个数和,询问独立。

Sol

不难发现答案即为求:\(r1 - l1 + r2 - l2 + r3 - l3 + 3 - siz\)。其中 \(siz\) 表示三个区间的公共颜色的个数。

仔细想想,发现这个东西和 \(bitset\) 维护种类数很像。

如果我们能使得相同的数也能一一对应,不就可以做了?

考虑在离散化的时候处理一下,发现直接去掉 \(unique\) 就能在中间空出空位。

设当前 \(s_i\) 的个数为 \(cur_{s_i}\)。我们只需要使 \(bitset[s_i + cur_{s_i}] = 1\) 就行了。

至此,我们已经会做 \(1\) 次询问了。

剩下的就简单了,直接套上莫队,空间开不下就跑 \(4\) 遍就行了。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <bitset>
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
	int p = 0, flg = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') flg = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		p = p * 10 + c - '0';
		c = getchar();
	}
	return p * flg;
}
void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}

const int N = 1e5 + 5, M = 2.5e4 + 5;

array <bitset <N>, M> ans;
array <int, N> s, h;

namespace Cpt {

int bsi = 357;

struct Node {

int l, r, id;
bool operator <(const Node &t) {
	if (l / bsi != t.l / bsi) return l < t.l;
	return (l / bsi) & 1 ? r < t.r : r > t.r;
}

};

array <int, N> cur;
bitset <N> isl;

void add(int x) {
	isl[s[x] + cur[s[x]]] = 1;
	cur[s[x]]++;
}

void del(int x) {
	cur[s[x]]--;
	isl[s[x] + cur[s[x]]] = 0;
}


}

array <Cpt::Node, 3 * M> qrl;
array <int, M> suf;

void solve(int &m) {
	int cnt = 0, idx = 0; Cpt::cur.fill(0);
	while (m && cnt <= (int)(2.5e4)) {
		cnt++, m--;
		ans[cnt].set();
		int l1 = read(), r1 = read(),
			l2 = read(), r2 = read(),
			l3 = read(), r3 = read();
		suf[cnt] = r1 - l1 + r2 - l2 + r3 - l3 + 3;
		idx++, qrl[idx].l = l1, qrl[idx].r = r1, qrl[idx].id = cnt;
		idx++, qrl[idx].l = l2, qrl[idx].r = r2, qrl[idx].id = cnt;
		idx++, qrl[idx].l = l3, qrl[idx].r = r3, qrl[idx].id = cnt;
	}
	sort(qrl.begin() + 1, qrl.begin() + 1 + idx);
	Cpt::isl = 0;
	int l = 1, r = 0;
	for (int i = 1; i <= idx; i++) {
		int x = qrl[i].l, y = qrl[i].r;
		while (l > x) l--, Cpt::add(l);
		while (r < y) r++, Cpt::add(r);
		while (l < x) Cpt::del(l), l++;
		while (r > y) Cpt::del(r), r--;
		ans[qrl[i].id] &= Cpt::isl;
	}
	for (int i = 1; i <= cnt; i++)
		write(suf[i] - 3 * ans[i].count()), puts("");
}

int main() {
	int n = read(), m = read();
	for (int i = 1; i <= n; i++)
		s[i] = h[i] = read();
	sort(h.begin() + 1, h.begin() + 1 + n);
	for (int i = 1; i <= n; i++)
		s[i] = lower_bound(h.begin() + 1, h.begin() + 1 + n, s[i]) - h.begin();
	while (m)
		solve(m);
	return 0;
}

标签:cur,int,兔子,while,Ynoi2016,array,include,Cpt,P4688
From: https://www.cnblogs.com/cxqghzj/p/17877747.html

相关文章

  • 7-5 兔子繁衍问题
    目录目录目录题目思路代码测评详情题目一对兔子,从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死,请问第1个月出生的一对兔子,至少需要繁衍到第几个月时兔子总数才可以达到N对?输入格式:输入在一行中给出一个不超过10000的正整数N......
  • 利用钢笔工具绘制插画(兔子+甜甜圈)
     视频网址:链接:https://pan.baidu.com/s/18ViCMg5WBozBt_gzXsK9BA提取码:c3dd--来自百度网盘超级会员V4的分享......
  • [Ynoi2016] 镜中的昆虫
    64MB,1.5s题目描述您正在欣赏galgame的HS,然后游戏崩溃了,于是您只能做数据结构题了:维护一个长为 \(n\) 的序列 \(a_i\),有 \(m\) 次操作。将区间 \([l,r]\) 的值修改为 \(x\)。询问区间 \([l,r]\) 出现了多少种不同的数,也就是说同一个数出现多次只算一个。......
  • python中实现兔子问题递推
     兔子一代生3对,然后每隔一代兔子才有繁殖能力,问最初有1对兔子,问5代后一共有多少只兔子?001、直接实现>>>list1=[1]*5>>>list1[1,1,1,1,1]>>>foriinrange(2,5):...list1[i]=list1[i-1]+list1[i-2]*3...>>>list1##1到5代......
  • [Ynoi2016] 这是我自己的发明(根号分治+分块/莫队)
    题目传送门soltion简单题换根显然可以拆成\(O(1)\)个区间,这里先不管。直接做法是莫队,把双子树拆成\(dfs\)序上的双前缀,可以直接莫队,但是常数比较大。另一种做法是根分,对颜色出现次数分治,大于的求出\(dfs\)序的前缀和即可,小于的因为一共只有\(O(n\sqrtn)\)个点对,所以......
  • 用Python画一只小兔子,祝您新年前途似锦,大展宏图
    用Python画一只小兔子,祝您新年前途似锦,大展宏图兔年到了,祝大家新年前途似锦!大展宏图!2021牛年,我用Python画了一头金牛,参考:Python画金牛2022虎年,我用Python画了一只小老虎,参考:Python画小老虎今年是第三年,还是一样的方式,今年画一只小兔子,为大家送上祝福。绘图过程录制成了如下视频,点......
  • python斐波那契兔子问题
    Python实现斐波那契兔子问题作为一名经验丰富的开发者,我将帮助你解决Python中的斐波那契兔子问题。在开始之前,让我们先了解一下整个解决问题的流程。接下来,我将为你提供每一步所需的代码,并对代码进行注释以帮助你理解。流程概述斐波那契兔子问题是一个经典的数学问题,其定义如下:......
  • python斐波那契数列兔子编程
    Python斐波那契数列兔子编程引言斐波那契数列是一个非常经典的数学问题,也是编程中常见的例题之一。它的起源可以追溯到古希腊数学家斐波那契(Fibonacci),他在13世纪的《算盘书》中首次提出了这个数列。斐波那契数列具有很多有趣的特性,而且在计算机科学中有广泛的应用。本文将通过Pyt......
  • 消失的兔子~~~
    做法想法:看数值都知道是二分把答案分成两个部分:左和右(把c=5e8-1)。问1的时候若回答是1:代表他在[1,5e8]里要不然就是[5e8+1,1e9]若在左:二分右边。右边相似找最后(若兔子是在右边),最早(若在左边)的点的值是1.再加或减掉c就可以啦~~~~ 具体代码:  ......
  • 781.森林中的兔子
    问题描述781.森林中的兔子(Medium)森林中有未知数量的兔子。提问其中若干只兔子"还有多少只兔子与你(指被提问的兔子)颜色相同?",将答案收集到一个整数数组answers中,其中answers[i]是第i只兔子的回答。给你数组answers,返回森林中兔子的最少数量。示例1:输入:answers......