首页 > 其他分享 >洛谷P8211 [THUPC2022 初赛] 搬砖

洛谷P8211 [THUPC2022 初赛] 搬砖

时间:2023-09-09 13:34:04浏览次数:38  
标签:p2 p1 洛谷 int 复杂度 初赛 leq P8211 buf

题目链接

以下设 \(B\) 为一个阈值,同时也表示值域分块的块长。

先考虑所有 \(b\) 都不为 \(0\) 的情况。对于一组询问,我们设一个 \(x\) 表示:当前已搬完所有 \(a\leq x\) 的砖。那么每次只可能是以下两种情况之一:

  1. 有至少一摞砖在当前这个单位时间内被搬完

    拿 \(x\) 加上 \(d\),之后拿 \(d\) 减去 \(\sum_{a_i\in[x+1,x+d+1]}b_i\)。

    \(\sum_{a_i\in[x+1,x+d+1]}b_i\) 的计算可以采用值域分块做到修改 \(O(\sqrt n)\),询问 \(O(1)\)

  2. 没有砖搬完

    结束此过程。

对于单组询问,我们尝试分析其时间复杂度:

  • \(d > B\)

    显然上述 \(1\) 操作最多执行 \(\frac{V}{B}\) 次。

  • \(d\leq B\)

    因为我们不关心 \(d=0\) 的情况,所以每个小时 \(d\) 都会减少。即 \(1\) 操作执行不超过 \(B\) 次。

修改只需要维护一下上述值域分块即可。总时间复杂度 \(O(T(B+\frac{T}{B})+V(B+\frac{V}{B}))\)。

但是,原命题中实际存在 \(b=0\) 的情况,也就是上述方法可能会在一些数据下变成 \(O(n)\) 的,那我们又该如何应对?

易发现,复杂度退化只会在 \(d\leq\sqrt V\) 的情况下产生。故而考虑维护一个 \(O(\sqrt n)\) 修改\(O(1)\) 查询 \(\geq i\) 的第一个非零位置值域分块。同时对于**每种 \(\leq\sqrt V\) 的 \(d\) **维护一个并查集,以求解 \(d\) 取当前值、\(x\) 为起点,最多能加到达哪里(具体操作见上述操作 \(1\),可以认为这个维护是在只考虑“如果没有任何一摞砖被搬完,小E就会停止工作”这一条件下进行的)。

于是询问中 \(d\leq B\) 的部分,就可以用这两个数据结构去维护 \(x,d\) 了。

时间复杂度多个 \(\log\),为并查集的复杂度(注意这里不能用按秩合并)。

点击查看代码
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
const int N = 1e5 + 170, C = 650;
int n, L, S;
inline char gc(){
    static char buf[100000], *p1 = buf, *p2 = buf;
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)? EOF : *p1++;
}
inline int read(){
    register char ch = gc(); register int sum = 0;
    while(!(ch >= '0' && ch <= '9')) ch = gc();
    while(ch >= '0' && ch <= '9') sum = sum * 10 + ch - 48, ch = gc();
    return sum;
}
inline void write(int x){
	if(x < 10){putchar('0' + x); return;}
	write(x / 10), putchar('0' + x % 10);
}
struct B1{
	int a[N + 10], t[C];
	void Upd(int x, int v){
		int b = x / L;
		FL(i, x, b * L + L - 1) a[i] += v;
		FL(i, b + 1, N / L) t[i] += v;
	}
	int Qry(int l, int r){
		l = min(l, N), r = min(r, N); 
		return a[r] + t[r / L] - a[l - 1] - t[(l - 1) / L];
	}
} b1, b2;
struct B3{
	int a[N + 10], t[C];
	B3(){fill(a, a + N + 1, 1e9), fill(t, t + C, 1e9);}
	void Upd(int x, int v){
		int b = x / L;
		FL(i, b * L, x) a[i] = min(a[i], v);
		FL(i, 0, b - 1) t[i] = min(t[i], v);
	}
	int Qry(int x){
		x = min(x, N); return min(a[x], t[x / L]);
	}
} b3;
struct DSU{
	int fa[N + 10];
	DSU(){FL(i, 0, N) fa[i] = i;}
	int F(int x){return fa[x] == x? x : fa[x] = F(fa[x]);}
} u[163];
int main(){
	n = read(), L = 160, S = N / L + 1;
	FL(id, 1, n){
		int op = read(), a, b, d, x = 0, ans = 0;
		if(op == 1){
			a = read(), b = read();
			b1.Upd(a, 1), b2.Upd(a, b);
			if(b) b3.Upd(a, a); int r = a;
			while(r < min(N, a + L) && !b1.Qry(r + 1, r + 1)) r++;
			FL(i, 1, L) FR(j, min(a - 1, r - i), a - i){
				if(j + i > N || j < 0 || u[i].fa[j] != j) break;
				u[i].fa[j] = j + i;
			}
		}
		else{
			d = read();
			while(d > 0){
				ans++; if(!b1.Qry(x + 1, x + d)) break;
				if(d <= L){
					int y = min(b3.Qry(x + 1), u[d].F(x));
					ans += (y - x - 1) / d, x += (y - x - 1) / d * d;
				}
				x += d, d -= b2.Qry(x - d + 1, x);
			}
			write(ans), putchar('\n');
		}
	}
	return 0;
}

标签:p2,p1,洛谷,int,复杂度,初赛,leq,P8211,buf
From: https://www.cnblogs.com/zac2010/p/17689341.html

相关文章

  • 洛谷P5556 圣剑护符
    题目链接先考虑如何判定一个集合是否存在两个异或和相同的子集\(s,t\),不然解决这道题就是无稽之谈。根据异或的优良性质,不妨在\(s,t\)中分别去掉\(s\capt\),之后从\(s\)中任意移动\(|s|-1\)个元素到\(t\)中去,易发现此时两个集合的元素异或和还是相同。也就是说,我们现......
  • CSP 2020 第一轮(初赛)模拟解析
    一、十进制数\(114\)的相反数的\(8\)位二进制补码是:A.\(10001110\)$\\\\\$B.\(10001101\) $\\\\\$C.\(01110010\) $\\\\\$D.\(01110011\)点击查看答案根据原码补码反码的有关定义可得:-114的源码为:01110010反码为:10001101......
  • 洛谷100题计划(20/100)
    洛谷100题计划(20/100)P1147连续自然数和-洛谷|计算机科学教育新生态(luogu.com.cn)题意就是找一段连续的区间,使得区间和为\(M\),很容易发现,其实这个区间就是一个等差数列,所以\(区间和=\frac{(首项+末项)\times项数}{2}\),假设首项为\(L\),末项为\(R\),那么可以得出......
  • 洛谷P3808 【模板】AC 自动机(简单版)题解 AC自动机模板题
    题目链接:https://www.luogu.com.cn/problem/P3808AC自动机模板题。示例程序:#include<bits/stdc++.h>usingnamespacestd;constintmaxn=1e6+5;structNode{intson[26],fail,id;Node(){}Node(int_id){memset(son,0,sizeof(son));......
  • NOIP2012提高组初赛易错题解析
    一.3. 错误原因:忘记了解析:Intel是全球最大的CPU厂商,AMD是世界上首个研发出7纳米CPU的厂商 6.错误原因:忘记了解析:ENIAC是世界上首台计算机,属于第一代计算机,即电子管计算机 10.错误原因:选项理解错误解析:A由蝙蝠,发明雷达是正确的,B因特网的发明与蜘蛛网无关,只是形......
  • NOIP2011提高组初赛易错题解析
    一.7.错误原因:不知道解析:快速排序在理论上最低的时间复杂度为O(n),但实际最低的时间复杂度为O(nlogn) 二.1.错误原因:漏项了解析:这棵树最少有12层,但题目是问可能是几层,所以还可能是2011层 5.错误原因:漏了一种情况解析:这道题的树有两种,所以答案也有两种 ......
  • 洛谷梗大全(5)
    引:洛谷梗大全(1)洛谷梗大全(2)洛谷梗大全(3)洛谷梗大全(4)\[\begin{aligned}&(−1)−1\times(4−5\times1^4)&=&0&&|&&1+1\times(45+1+4)&=&51&\\&1^{(1−4−5^{14})}&=&1&&|&&1-1\times(4-51-4)&......
  • 洛谷梗大全(4)
    \[\Large\boxed{今日运势}\]\[\Large\bold{\color{#8E44AD}Lovely\_Chtholly\\color{black}的运势}\]\[\Huge\color{#E74C3C}\textbf{§}\bold{\吉你钛镁\}\textbf{§}\]\[\scriptsize\text{你已经在洛谷连续打卡了}\normalsize\infty\scriptsize\text{......
  • 洛谷P1228 地毯填补问题
    1#include<bits/stdc++.h>2usingnamespacestd;3intk,x,y;45intjudge(intx,inty,intgx,intgy,intlen)//判断障碍物在哪个区块6{7if(gx<=x+len/2-1&&gy<=y+len/2-1)8return1;9else......
  • 洛谷 P3373 总结
    洛谷P3373题意给定长度为\(n\)的整数序列,有以下三种操作共\(q\)次:将区间\([l,r]\)每一个数乘上\(k\);将区间\([l,r]\)每一个数加上\(k\);求出区间\([l,r]\)的区间和对\(m\)取模后的结果。\(1\leqslantn,q\leqslant10^5\)。思路这个题非常明确......