首页 > 其他分享 >11月22改题(NOIP 模拟赛)

11月22改题(NOIP 模拟赛)

时间:2022-11-23 11:22:20浏览次数:56  
标签:11 ch NOIP int mid 改题 read ans define

T1 触手

思路:

第一问很简单,用 st 表维护区间最小值,再用线段树做区间修改,再单点查询最终的高度,相加即可;

第二问是一个贪心,不难发现,对于所有最终的高度,覆盖一段高度连续的区间肯定是最优的。

设 \(k\) 表示连续高度的区间个数, \(num_i\) 表示第 \(i\) 个连续高度的区间的元素个数,即 \(\sum_{i=1}^k\left\lceil\dfrac{h_i}{x}\right\rceil\)

改后代码(100 pts):

#include <bits/stdc++.h>
#define int long long 
#define rint register int 
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define mod 998244353
#define inf 0x3f3f3f3f3f3f3f3f
#define ls p<<1
#define rs p<<1|1
#define inf 0x3f3f3f3f3f3f3f3f 
using namespace std;

inline int read() {
	rint 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^48);ch=getchar();}
	return x*f;
}

const int N = 2e5 + 10;

struct Node {
	int l, r, mx, tag;
} t[N << 2];

int n, x, a[N], st[N][30], h[N], S, ans; 

int Ask(int l, int r) {
	int k = __lg(r - l + 1);
	return min(st[l][k], st[r - (1 << k) + 1][k]);
}

void pushup(int p) {
	t[p].mx = max(t[ls].mx, t[rs].mx);
}

void brush(int p, int x) {
	t[p].mx = max(t[p].mx, x);
	t[p].tag = max(t[p].tag, x);
}

void pushdown(int p) {
	if(t[p].tag) {
		brush(ls, t[p].tag);
		brush(rs, t[p].tag);
		t[p].tag = 0;
	}
}

void build(int p, int l, int r) {
	t[p].l = l, t[p].r = r;
	t[p].mx = -inf;
	if(l == r) return ;
	int mid = l + r >> 1;
	build(ls, l, mid); build(rs, mid + 1, r);
	pushup(p);
}

void update(int p, int l, int r, int x) {
	if(l <= t[p].l && t[p].r <= r) {
		brush(p, x);
		return ;
	}
	pushdown(p);
	int mid = t[p].l + t[p].r >> 1;
	if(l <= mid) update(ls, l, r, x);
	if(r > mid) update(rs, l, r, x);
	pushup(p);
}

int query(int p, int l, int r) {
	if(l <= t[p].l && t[p].r <= r) {
		return t[p].mx;
	}
	pushdown(p);
	int mid = t[p].l + t[p].r >> 1, ans = -inf;
	if(l <= mid) ans = max(ans, query(ls, l, r));
	if(r > mid) ans = max(ans, query(rs, l, r));
	pushup(p);
	return ans;
}

signed main() {
  freopen("xyx.in", "r", stdin);
  freopen("xyx.out", "w", stdout);
  n = read(), x = read();
  For(i,1,n) a[i] = read(), st[i][0] = a[i];
  for (int j = 1; (1 << j) <= n; j++) {
  	for (int i = 1; i + (1 << j) - 1 <= n; i++) {
  		st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
		}
	}
	build(1, 1, n);
	For(i,1,n - x + 1) update(1, i, i + x - 1, Ask(i, i + x - 1));
	For(i,1,n) h[i] = query(1, i, i), S += h[i];
	int num = 1;
	For(i,1,n+1) {
		if(h[i] == h[i+1]) num++;
		else {
			ans += ceil((double)num * 1.0 / x);
			num = 1;
		}
	}
	cout << S << '\n' << ans << '\n';
  return 0;
}

标签:11,ch,NOIP,int,mid,改题,read,ans,define
From: https://www.cnblogs.com/Daniel-yao/p/16917672.html

相关文章

  • 11月23日总结
    今天干了啥:Python3集合打算干啥:Python3编程第一步代码数:291......
  • P1002 过河卒 详细题解 搜索回溯+递归 [NOIP2002 普及组]
    题目描述棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方......
  • Dev-C++5.11安装教程
    (目录)一、下载1.介绍原公司Bloodshed已经停止开发Dev-C++了,但是Embarcadero开发着一个Dev-C++的分支。详见:https://www.embarcadero.com/cn/free-tools/dev-c......
  • CSP-J/S & NOIP 常用板子大全 !
    HNCSP-J/S2022RP++!序号算法①SPFA②并查集③最小生成树④拓扑排序⑤堆⑥字典树N懒得加了1.SPFA题目链接题目描述输入......
  • 11.23.2022 篮球总结
    转髋-----胳肢窝   左脚瞄准镜    侧合球上篮外脚后撤步左手变向传球拆--------夹小臂 90 顿膝盖--------------挖步转髋提前蹲+全力身侧运球-------------------......
  • S1 - Lesson 11 - 12
    whosewhowhosepen/car blueYouarebluetoday.[忧郁的]It'sabluemovie.[不健康的]blueblood.[贵族的] perhaps[大概]Perhapsitis.Perhapsso.Perha......
  • Java.11.22
    一.while循环1.while是最基本的循环,它的结构为:while(布尔表达式){//循环内容}2.只要布尔表达式为true,循环就会一直执行下去。3.我们大多数......
  • GL-Talking about rules 20221122
    TimeTalkingaboutrulesDidyouhavestrictrulestofollowwhenyouwereateenager?Discusswhatguidelinesamodernfamilyshouldfollow?Teenagersshouldn......
  • 2022-11-22-6
    1packagecn.itsource._inputsteam;23importjava.io.FileInputStream;4importjava.io.FileNotFoundException;5importjava.io.FileOutputStream;6imp......
  • 【个人内卷1年计划】2022年11月22日记录
    2022-11-22计划1.内卷1年每天内卷1个小时【包括加班】周末每天8个小时【包括加班】每两个月一次周六日非下雨天,必须出去社交,丧心病狂的玩每两周写整理一篇博客不下......