首页 > 其他分享 >「KDOI-06-S」消除序列 题解

「KDOI-06-S」消除序列 题解

时间:2024-09-27 12:12:35浏览次数:1  
标签:06 min int 题解 sum KDOI num MAXN aligned

分享一个应该很少人想到的做法。

首先贪心地想,第一种操作肯定最多选择一次。比如如果选择了下标 \(i\) 和 \(j\) 进行第一种操作,那么就等价于在 \(\max\{i,j\}\) 进行了一次操作。由于代价是非负数,则我们最多只用执行一次。当然也可以不使用这种操作

有了这个思路,我们先考虑不使用第一种操作的最优答案,很明显就是 \(\begin{aligned} \sum _{i \notin P}b_i\end{aligned}\)。

接着再考虑使用一次的情况。我们先假定在位置 \(j\) 处进行一次第一种操作,这就表示 \([1,j]\) 的所有数字都变成了 \(0\),我们将 \(i\in P \wedge i\in [1,j]\) 的所有 \(i\) 统计到集合 \(A\) 中,将 \(i \notin P \wedge i \notin [1,j]\) 的所有 \(i\) 统计到集合 \(B\) 中。这个时候不难发现 \(A\) 中的元素都是应当为 \(1\) 但是因为在 \(j\) 进行了第一种操作后变成 \(0\) 的下标,那么我们就要把它们全部再变为 \(1\);而在 \(B\) 中的元素则是不应当为 \(1\) 但是还保持初始状态 \(1\) 的下标,我们需要一个一个地将它们变为 \(0\)。则此时答案就是:

\[\begin{aligned}\min\{a_j+(\sum_{i\in A}c_i)+(\sum _{i\in B}b_i) \}\end{aligned} \]

但是数据范围不允许我们枚举 \(j\)。其实我们不难发现当 \(j\in [p_i,p_{i+1}-1]\) 时 \(A\) 和 \(B\) 两个集合是不变的。则代入上述式子唯一改变的就是 \(a_j\) 的值。而且题目中提到 \(\sum m\leq 5\times 10^5\),这说明 \(|A|\) 会很小,但是 \(|B|\) 有可能会很大,因此我们提前预处理出 \(\begin{aligned}sum_i=\sum _{k=1}^ib_k \end{aligned}\),则 \(\begin{aligned} \sum_{i\in B}b_i=sum_n-sum_j-num \end{aligned}\),其中 \(\begin{aligned}num=\sum_{k\in P\wedge k\in [j+1,n]}b_k\end{aligned}\)。\(num\) 可以一步一步推得,因此计算量相对减少了很多。我们再代入进原式:

\[\min\{a_j+(\sum_{i\in A}c_i)+sum_n-sum_j-num\} \]

考虑到当前 \(j\) 枚举的区间保证 \(A\) 和 \(B\) 不变,转换一下得到:

\[\min\{a_j-sum_j\}+(\sum_{i\in A}c_i)-num+sum_n \]

不难发现 \(\min\{a_j-sum_j\}\) 中的 \(a_j\) 和 \(sum_j\) 都不会被修改,因此我们可以用 ST 表记录 \(a_j-sum_j\) 的最小值。然后我们就可以在规定的数据范围内通过了。

代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=5e5+5;
int n,m,q;
int p[MAXN];
int a[MAXN],b[MAXN],c[MAXN];
int sum[MAXN],st[MAXN][20];
int lg[MAXN];
int query(int l,int r)
{
	int k=lg[r-l+1];
	return min(st[l][k],st[r-(1<<k)+1][k]);
}
void read(int &x)
{
	x=0;
	short flag=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-')	flag=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	x*=flag;
}
signed main()
{
	read(n);
	for(int i=2;i<=n;i++)	lg[i]=lg[i>>1]+1;
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<20;j++)	st[i][j]=1e15;
	}
	for(int i=1;i<=n;i++)	read(a[i]);
	for(int i=1;i<=n;i++)	read(b[i]),sum[i]=sum[i-1]+b[i];
	for(int i=1;i<=n;i++)	read(c[i]);
	for(int i=1;i<=n;i++)	st[i][0]=a[i]-sum[i];
	for(int j=1;j<=19;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]);
	}
	read(q);
	while(q--)
	{
		read(m),p[m+1]=n+1;
		for(int i=1;i<=m;i++)	read(p[i]);
		int minn=sum[n],num=0,rsum=0,minx=n+1;
		for(int i=1;i<=m;i++)	minn-=b[p[i]],rsum+=b[p[i]],minx=min(minx,p[i]);
		if(minx>1)	minn=min(minn,query(1,minx-1)+sum[n]-rsum);
		for(int i=1;i<=m;i++)	num+=c[p[i]],rsum-=b[p[i]],minn=min(minn,query(p[i],p[i+1]-1)+sum[n]+num-rsum);
		cout<<minn<<endl;
	}
	return 0;
}

标签:06,min,int,题解,sum,KDOI,num,MAXN,aligned
From: https://www.cnblogs.com/SuporShoop/p/18435415

相关文章

  • 「TAOI-2」Ciallo~(∠・ω< )⌒★ 题解
    手玩了一个小时终于做出来了,这不得写一篇题解记录一下??下面设\(s\)的长度为\(n\),\(t\)的长度为\(m\)。考虑分类讨论:如果\(s\)中有一个子串\(s'\)与\(t\)完全相同(可以用哈希进行比较),设\(s'\)是\(s\)的第\(l\)到第\(r\)个字符组成的字符串,则我们可以删除\([1,......
  • 三星G8 OLED显示器S34BG850SC,使用DP线连接电脑,显示器黑屏问题解决。
    这个问题在网上好像很多人问,但是每个人的情况不同,总之我也是遇到了。事情大概:PC机显卡的DP口通过显示器自带的MiniDP线和显示器相连,这个没什么好说的了,原配只送MiniDP线,想必买这台显示器的人都是先用的这根线。然而我有一台NUC,通过雷电口也连接到了这台显示器。所以我这台G8是......
  • [TJOI2010] 天气预报 题解
    分析一下题目,大致意思就是给定一组常数\(a_i\),然后有一个递推式\(w_i=\sum_{j=1}^{n}w_{i-j}\timesa_{j}\),让你求出\(w_m\)对于\(4147\)取模的值。根据这个\(1\leqm\leq10^7\)的恐怖范围,姑且算到了\(O(m)\)的时间复杂度。但是观察一下这个递推式,发现\(O(m)\)跑......
  • ABC262G 题解
    LISwithStack观察到\(n\le50\),考虑区间dp。设\(dp(l,r,x,y)\)表示区间\([l,r]\)中选出的子序列的最小值\(\gex\),最大值\(\ley\)的方案数。根据栈的性质,设元素\(x\)入栈的时间为\(in_x\),出栈时间为\(out_x\),那么所有元素构成的区间\([in_x,out_x]\)两......
  • P10681 COTS/CETS 2024 奇偶矩阵 Tablica
    P10681COTS/CETS2024奇偶矩阵Tablica来自qnqfff大佬的梦幻dp。约定二元组\((n,m)\)表示一个\(n\)行\(m\)列的矩形。不添加说明的子问题,限制与题面一致。思路先考虑放最后一行,发现你填的位置经过变换后可以得到其他的结果,也就是说只要乘上变换的方案数就可以任......
  • 2024-2025专题二题单 - 题解
    A-MoneyinHand(记忆化搜索)原题链接题解B-GoodGraph(并查集)原题链接题解C-IceSkating(dfs求连通块)原题链接题解D-TheLakes(dfs求连通块,连通块内累加,多组数据注意初始化)原题链接题解E-LearningLanguages(建图,dfs统计连通块个数,答案为个数-1)原题链接题......
  • Python画笔案例-064 绘制彩花之旋转羽毛
    1、绘制彩花之旋转羽毛通过python的turtle库绘制彩花之旋转羽毛,如下图:2、实现代码 绘制彩花之旋转羽毛,以下为实现代码:"""彩花之旋转羽毛.py本程序需要coloradd模块支持,安装方法:pipinstallcoloradd技术支持微信scartch8,QQ:406273900www.lix......
  • 进击的奶牛题解
    题目描述FarmerJohn建造了一个有 N(2≤N≤105)个隔间的牛棚,这些隔间分布在一条直线上,坐标是 x1,x2,⋯ ,xN​(0≤xi≤109)。他的 C(2≤C≤N)头牛不满于隔间的位置分布,它们为牛棚里其他的牛的存在而愤怒。为了防止牛之间的互相打斗,FarmerJohn想把这些牛安置在指定的隔间,所......
  • 奶牛分厩题解
    题目描述农夫约翰有 N(1≤N≤5000)头奶牛,每头奶牛都有一个唯一的不同于其它奶牛的编号 s[i],所有的奶牛都睡在一个有 K 个厩的谷仓中,厩的编号为 00 到 K−1。每头奶牛都知道自己该睡在哪一个厩中,因为约翰教会了它们做除法,Si mod K的值就是第 i 头奶年所睡的厩的编......
  • 易优cms安全设置常见问题_Eyoucms安全设置问题解决方法
    易优EyouCMS的安全设置对于保护网站免受攻击非常重要。下面列出了一些关于易优CMS安全设置的常见问题及其解决方法:1.目录权限设置为了防止未经授权的访问,应该合理设置网站目录的权限。例如,上传目录通常需要写入权限,而其他目录则应限制权限以防止恶意文件上传或执行。解决方法......