首页 > 其他分享 >「NOIP 模拟赛 20230705」序列删数问题

「NOIP 模拟赛 20230705」序列删数问题

时间:2023-07-06 17:55:54浏览次数:40  
标签:20230705 NOIP 删除 int sk -- 删数 id

summarization

solution

首先发现,范围小的工具在删除某一数字时将更大数字包括进来的可能性越小,可以删除的数更多,所以在删除某一数字时应该尽可能选择范围较大的工具。

接下来我们考虑可删数(要删除的数)删除的顺序:

考虑要删掉每个数所允许的最大的工具的区间长度。现在假设有两个可删数:小数和大数。大数的两边某个位置被两个不可删去的比它更大的数占据了,于是它所允许的工具长度被这两个不可删去的数限制。然而,小数却有至少一边是被可删去的大数限制的。

此时我们考虑,若我们删去小数,则大数允许的区间长度会变小;若删去大数,则小数允许的区间长度会变大,变得更容易删去。因此我们应该先删除大的可删数。

于是,我们从大到小删除可删数。对于某一个可删数,我们使用能使用的最大的工具。若所有工具都无法使用,则输出 NO。如果所有可删数都被删除,则输出 YES

在代码实现上,对于找每个可删数左右离它最近的比它大的数,可以使用单调栈+二分。在单调栈时,无需考虑可删数及其变化,因为我们删除的顺序,比某个可删数大的可删数已经在它之前被删除了,而比它小的则不会影响边界。

对于删除,我们不必在删除某个数时真的把他删掉,因为这个数被删除只会影响接下来查询的区间长度,所以只需要在这个数上打个标记,在单调栈找到区间后将区间长度减掉这个区间中已经删除的数的个数即为这个区间真正的长度,用一个单点修改区间查询的数据结构即可。

code

CI N = 2e5, INF = 0x7fffffff; int T, n, m, a[N + 5], p[N + 5], l[N + 5], pp[N + 6]; set <int> s; int num[N + 5], c[N + 5], sk[N + 5], top = 0, L[N + 5], R[N + 5]; bool vis[N + 5];
int lowbit (int x) {return x & -x;}
void add (int id, int x) {for (; id <= n; id += lowbit (id)) c[id] += x;}
int sum (int id) {int s = 0; for (; id; id -= lowbit (id)) s += c[id]; return s;}
void D () {
	RI i, j; Mt (sk, 0); top = 0; for (i = 1; i <= n; ++ i) {
		if (! vis[i]) {W (top && sk[top] < a[i]) -- top; sk[++ top] = a[i];}
		else {int it = upper_bound (sk + 1, sk + top + 1, a[i], greater <int> ()) - sk; if (it == 1) L[i] = 1; else L[i] = pp[sk[it - 1]] + 1;}
	} Mt (sk, 0); top = 0; for (i = n; i >= 1; -- i) {
		if (! vis[i]) {W (top && sk[top] < a[i]) -- top; sk[++ top] = a[i];}
		else {int it = upper_bound (sk + 1, sk + top + 1, a[i], greater <int> ()) - sk; if (it == 1) R[i] = n; else R[i] = pp[sk[it - 1]] - 1;}
	} return ;
}
void init () {Mt (c, 0); s.clear (); Mt (num, 0); Mt (L, 0); Mt (R, 0); Mt (vis, 0);}
void get () {
	RI i, j; for (Read (n, m), i = 1; i <= n; ++ i) Read (a[i]), pp[a[i]] = i;  for (i = 1; i <= m; ++ i) Read (p[i]), vis[p[i]] = 1, p[i] = a[p[i]];
	sort (p + 1, p + m + 1); for (i = 1; i <= m; ++ i) Read (l[i]), s.insert (l[i]), ++ num[l[i]]; D (); for (i = m; i >= 1; -- i) {
		int id = pp[p[i]]; int len = (R[id] - L[id] + 1) - (sum (R[id]) - sum (L[id] - 1));
		if (num[len] > 0) {-- num[len]; if (num[len] == 0) s.erase (len);}
		else {
			set <int> :: iterator it = s.insert (len).first; if (it == s.begin ()) {printf ("NO\n"); return ;}
			-- it; int co = *it; -- num[co]; if (num[co] == 0) s.erase (co); s.erase (len);
		} add (id, 1);
	} printf ("YES\n");
}
int main () {
	RI i, j; Read (T); W (T --) {init (); get ();}
	return 0; 
}

标签:20230705,NOIP,删除,int,sk,--,删数,id
From: https://www.cnblogs.com/ClapEcho233/p/17529734.html

相关文章

  • 「NOIP 模拟赛 20230706」偷 WiFi
    summarization有一个长度为\(n\)的序列\(p\),将其中若干个数标记。对于序列中的每一个位置\(i\),其贡献为其左边与右边离它最近的被标记的数的数值的和。求出最大的贡献总和。(\(1\len\le2\times10^6\))solution首先显然,\(p_1,p_n\)一定要标记。然后考虑分别求相邻的标记数......
  • SSO2.0 20-20230705
                   ......
  • 「NOIP 模拟赛 20230705」T2-序列删数问题 题解
    题面Natsuzora有一个长度为\(n\)的排列\(a_1,a_2,\ldots,a_n\),他想要将序列中的\(m\)个数删除。删除数字需要使用到“魔法工具”,其也有\(m\)种,其中第\(i\)种魔法工具能够将排列中任意一个的长度为\(l_i\)的区间中最大的数删除。每个魔法工具最多只能使用\(1\)次。......
  • 成语积累 20230705
    焚膏继晷:焚:点燃;膏:灯油或蜡烛;继:接续;晷:日影或日光。意思是点燃灯烛来接替日光照明。形容夜以继日的用功读书或努力工作。例句:~,兀兀穷年。鹤唳华亭:表示思念,怀旧之意。亦为慨叹仕途险恶,人生无常之词。例句:但~,贵何似贱;珠沉金谷,富不如贫。拾人牙慧:牙慧:牙齿内剔出的余食。比喻拾取别人......
  • [NOIP2012 普及组] 寻宝
    思路:模拟必须mod20123,不然就有可能会爆掉!AC代码#include<iostream>#defineintlonglongusingnamespacestd;boolwhether[10001][101];ints[10001][101],T[10001];signedmain(){ intn,m,S,w,ans=0; cin>>n>>m; for(inti=0;i<n;i++) { for(intj=......
  • NOIP 模拟赛 2023.07.04 题解--zhengjun
    linkT1转化为\((b_i,a_i)\)与\((b_j,a_j)\)之间的斜率。发现性质(省略),只需要计算相邻两个点之间的答案即可,用set就行了。T2先找性质,发现即为\(a,b,c\)各有某一位是“独特”(即其他两个数这一位与之不一样)的。直接\(O(8^2n)\)记录各个状态,预处理转移优化一下即可。T......
  • P1025 [NOIP2001 提高组] 数的划分
    https://www.luogu.com.cn/problem/P1025#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>usingnamespacestd;constintN=10;intn,k;intans;intst[N];voiddfs(intlast,intleft,intstep)//利用last来......
  • [NOIP2006 普及组] 开心的金明
    该s的背包[NOIP2006普及组]开心的金明题目描述金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过\(N\)元钱就行”。今天一早金明就开始做预算,但是他想买的......
  • [NOIP2015 提高组] 跳石头
    [NOIP2015提高组]跳石头题目背景一年一度的“跳石头”比赛又要开始了!题目描述这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有\(N\)块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从......
  • [NOIP2001 提高组] 一元三次方程求解
    [NOIP2001提高组]一元三次方程求解题目描述有形如:\(ax^3+bx^2+cx+d=0\)这样的一个一元三次方程。给出该方程中各项的系数(\(a,b,c,d\)均为实数),并约定该方程存在三个不同实根(根的范围在\(-100\)至\(100\)之间),且根与根之差的绝对值\(\ge1\)。要求由小到大依......