首页 > 其他分享 >P9744题解

P9744题解

时间:2024-01-19 15:33:49浏览次数:32  
标签:P9744 ch int 题解 sum while 操作

P9744 「KDOI-06-S」消除序列

题目传送门

题解

记错时间错过模拟赛的 sb 来也。

题目中的最关键信息就是 \(a_i,b_i,c_i\ge 0\),这意味着多做无用的操作一定不优,所以有:

  • 结论 \(1\):优先进行 \(1\) 操作。
    这是因为我们不管我们在 \(1\) 操作前做什么操作都会被其推平覆盖,是无用操作。

  • 结论 \(2\):最多只进行一次 \(1\) 操作。
    也是显然的,我们一定会保留范围最广的一次 \(1\) 操作,这样其他 \(1\) 操作都是无用操作。

到这里,一个显然的想法就出现了:枚举 \(1\) 操作的 \(i\),并通过前后缀和快速计算其他操作的最小代价。

然而这会是 \(O(nq)\) 的,难以通过。

观察数据范围里出现了一个神奇的东西:\(\sum m\),所以我们的目标是推出一个单次询问复杂度带 \(m\) 的算法。

然后我们开始小小的推一波式子:设 \(1\) 操作的位置 \(i\) 满足 \(p_j\le i<p_{j+1}\),那么易知此时的代价为 \(a_i+\sum_{k=i+1}^n b_k+\sum_{k=1}^j c_{p_k}-\sum_{k=j+1}^m b_{p_k}\)。

对于同样的 \(j\),后面的 \(\sum_{k=1}^j c_{p_k}-\sum_{k=j+1}^m b_{p_k}\) 贡献一定,所以我们只要快速求出区间中前两项的最小值,刚好,前两项只与 \(i\) 有关,所以我们可以使用 ST 表或线段树来解决。

最后再考虑一下不使用 \(1\) 操作的情况即可。

复杂度 \(O(\sum m\log n)\)。

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read() {
	int s=0,m=0;char ch=getchar();
	while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
	while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
	return m?-s:s;
}
int n,q,a[500005],b[500005],c[500005];
int p[500005],prec[500005],sufb[500005];
struct Sparse_Table {
	int st[500005][25];
	void init(int n,int v[]) {
		memset(st,0x3f,sizeof(st));
		for(int i=1;i<=n;i++) st[i][0]=v[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]);
	}
	int query(int l,int r) {
		if(l>r) return INT_MAX;
	    int k=log2(r-l+1);
	    return min(st[l][k],st[r-(1<<k)+1][k]);
	}
} st;//ST 表
signed main() {
	cin>>n;
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=1;i<=n;i++)
		b[i]=read();
	for(int i=1;i<=n;i++)
		c[i]=read();
	int sum=0;
	for(int i=n;i;i--)
		a[i]+=sum,sum+=b[i];
	st.init(n,a);
	cin>>q;
	while(q--) {
		int m=read();
		for(int i=1;i<=m;i++) 
			p[i]=read();
		prec[0]=sufb[m+1]=0;
		for(int i=1;i<=m;i++)
			prec[i]=prec[i-1]+c[p[i]];
		for(int i=m;i;i--)
			sufb[i]=sufb[i+1]+b[p[i]];
		int ans=sum-sufb[1];//不使用 1 操作
		ans=min(ans,st.query(1,p[1]-1)-sufb[1]);//第一段
		for(int i=1;i<m;i++) 
			ans=min(ans,st.query(p[i],p[i+1]-1)+prec[i]-sufb[i+1]);
		ans=min(ans,st.query(p[m],n)+prec[m]);//最后一段
		printf("%lld\n",ans);
	}
	return 0;
}

标签:P9744,ch,int,题解,sum,while,操作
From: https://www.cnblogs.com/operator-/p/17974776

相关文章

  • P8047题解
    P8047[COCI2015-2016#4]GALAKSIJA题目传送门题解显然是要删边变加边的,然后联通性也是显然要用并查集维护的,就是路径异或和需要一个数据结构来维护。发现:加边删边不影响两个点的路径异或和。所以我们可以处理出每个点到\(1\)号节点的路径异或和\(d\),于是\(Path_{u,v}=d_u......
  • P8034题解
    P8034[COCI2015-2016#7]Ozljeda题目传送门题解评橙差不多了。手玩一下样例,很容易发现\(x\)的循环节为\(K+1\),每一段分别为\(a_1,a_2,a_3,\dots,a_K,\bigoplus_{i=1}^Ka_i\)这几项,然后恰好循环节的异或值为\(0\),所以就可以直接维护前缀异或值,然后取模求答案。代码:#i......
  • [AGC048D] Pocky Game 题解
    题目链接点击打开链接题目解法好难的题,想不出来一点!!!首先给出一个第一个结论:最优策略下,每个人每次只会取一个石子或者取完一堆石子题解区都没有严谨证明,\(at\)的\(editorial\)也没证,所以我只能感性理解:下面以先手为例。如果最左边的石子数\(>\)其余所有堆的石子数,那么先......
  • 题解 WD与数列
    P5161WD与数列可以想到原条件是一个差分形式,所以我们对原数组差分。然后发现答案其实就是\(\sum_{i<j}\min(lcp(i+1,j+1)+1,j-i)\)。这个东西先跑SA,然后建笛卡尔树。考虑对于一个区间,其值为\(x\)。那么相当于是求\(\sum_{l\inS,r\inT}\min(|sa_{l}-sa_{r}|,x)\)。笛......
  • AT_arc115_b [ARC115B] Plus Matrix 题解
    AT_arc115_b[ARC115B]PlusMatrix题解题意给定矩阵\(C_{n\timesn}\),求两个数列\(A_n,B_n\),使得\(C_{i,j}=A_i+B_j\)。分析画出一个表格来:213243502131324可以看出来,对于任意一列\(j\),\(C_{*,j}\)都存在有\(B_j\)的贡献。那么我们......
  • ELK之Filebeat自动断开问题解决
     自动断开命令 解决自动断开命令nohup./filebeat-e-cfilebeat.yml>./filebeat.log 2>&1& disown 其他的方式(目前我没有使用) 在linux操作系统/etc/systemd/system目录下创建一个filebeat.service文件,写入如下内容需要注意替换文件的位置以及版本[Unit]D......
  • GDKOI 2024 题解
    鸽了一些题。匹配先抽出来一个完美匹配,然后尝试调整。调整相当于:找一个偶环,满足匹配的边和未匹配的边交错,且偶环的总异或和为\(0\),是不是写个暴力就好了?发现冲过去了,很牛逼,复杂度\(O(n^3)\)(?),Code。不休陀螺一个区间可以被打出的条件是:令\(\Delta_i=b_i-a_i\),则\(x=\sum......
  • P2580 于是他错误的点名开始了题解
    “普及/提高-”这个难度很有意思。说明这题可能需要用到提高组当中比较基础的内容。它的名字叫做map。map,其实相当于一个超大数组,但它真实的作用是:映射。比如a[7]=5;就是用a数组把7和5关联了起来,这个操作就叫映射。map这东西NB的地方在于,它能这么写:score["Leo201......
  • P9012 [USACO23JAN] Moo Operations B题解
    第1道赛场AC的题,必须发篇题解记录一下。Tips:\(1\le|S|\le100\)——题目才100,这就可以随便整活了。如果你稍微懂点英语,就会知道第\(2\sim4\)个点的\(S\)都最多只有\(3\)个字符,而目标“MOO”也是\(3\)个字符,所以只需要模拟就可以了。intcheck(string......
  • [GFCTF 2021]web部分题解(更新中ing)
    [GFCTF2021]Baby_Web拿源码环节:打开环境(◡ᴗ◡✿)乍一看什么都没有,F12下没看到js文件,但是看到了出题师傅的提示:“源码藏在上层目录xxx.php.txt里面,但你怎么才能看到它呢?”这时候在思考文件在上层目录中,既然是目录下那就试一下dirsearch扫描先看看后台都有什么(这里就直接......