首页 > 其他分享 >题解 P8165 [eJOI2021] AddK

题解 P8165 [eJOI2021] AddK

时间:2023-09-08 11:36:37浏览次数:31  
标签:eJOI2021 int 题解 sum times P8165 AddK ll

不知道为什么这道题还没有题解。

Solution

对于操作 \(1\),由于 \(K\le 10\),直接暴力单点修改即可。
而操作 \(2\) 的询问,不难发现,最后结果的呈现形式是

\[1\times A_l+2\times A_{l+1}+3\times A_{l+2}+...+3\times A_{r-2}+2\times A_{r-1}+1\times A_r \]

其中中间可能有一段系数均为 \(m\) 的项。那么为了维护这样的形式,我们不仅要维护 \(\sum A_i\),还要维护 \(\sum i\times A_i\),这样左边的 \(1\times A_l+2\times A_{l+1}+3\times A_{l+2}+...\) 就可以变为 \(\sum\limits_{i=l}^{l+m-1}i\times A_i -(l-1)\times\sum\limits_{i=l}^{l+m-1}A_i\) 而直接计算了。

Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+5;
int n,K,Q,t[11];
ll a[N],sum[N<<2],isum[N<<2];
void pushup(int u){sum[u]=sum[u<<1]+sum[u<<1|1],isum[u]=isum[u<<1]+isum[u<<1|1];}
void build(int u,int l,int r){
	if(l==r)return sum[u]=a[l],isum[u]=1ll*l*a[l],void();
	int mid=(l+r)/2;
	build(u<<1,l,mid);build(u<<1|1,mid+1,r);
	pushup(u);
}
void upd(int p,ll k,int u=1,int l=1,int r=n){
	if(l==r)return sum[u]=k,isum[u]=1ll*l*k,void();
	int mid=(l+r)/2;
	p<=mid?upd(p,k,u<<1,l,mid):upd(p,k,u<<1|1,mid+1,r);
	pushup(u);
}
ll ask(ll *S,int p,int q,int u=1,int l=1,int r=n){
	if(p>q)return 0;
	if(p<=l&&r<=q)return S[u];
	int mid=(l+r)/2;ll res=0;
	if(p<=mid)res+=ask(S,p,q,u<<1,l,mid);
	if(q>mid)res+=ask(S,p,q,u<<1|1,mid+1,r);
	return res;
}
int main(){
	scanf("%d%d",&n,&K);
	for(int i=1;i<=n;i++)scanf("%lld",a+i);
	build(1,1,n);
	scanf("%d",&Q);
	for(int T=1,o;T<=Q;T++){
		scanf("%d",&o);
		if(o==1){
			for(int i=1;i<=K;i++)scanf("%d",t+i);
			ll at1=a[t[1]];
			for(int i=1;i<K;i++)upd(t[i],a[t[i]]=a[t[i+1]]);
			upd(t[K],a[t[K]]=at1);
		}else{
			ll l,r,m;
			scanf("%lld%lld%lld",&l,&r,&m);
			int len=r-l+1;ll res=0;
			if(len<m){puts("0");continue;}
			else if(len==1){printf("%lld\n",ask(sum,l,r));continue;}
			res=m*ask(sum,l,r);
			res+=ask(isum,l,l+m-1)-(l+m-1)*ask(sum,l,l+m-1);
			res+=(r-m+1)*ask(sum,r-m+1,r)-ask(isum,r-m+1,r);
			printf("%lld\n",res);
		}
	}
	return 0;
}

标签:eJOI2021,int,题解,sum,times,P8165,AddK,ll
From: https://www.cnblogs.com/aday526/p/solution-p8165.html

相关文章

  • SP8177 题解
    2023-09-0111:29:13solution题意:每次询问\([l,r]\)内有多少个数满足可以被所有非\(0\)数位整除。思路看到这个数据范围和题目描述,显然是数位dp。因为\(1\sim9\)的最小公倍数是\(2520\),并且\(2520\)是其他所有\(1\sim9\)子集的最小公倍数的倍数,所以我们只需要......
  • CF402D 题解
    2023-09-0418:42:46solution不难想到我们要先记录一下每一位的前缀\(\gcd\),我们发现我们选择一位的前缀\(\gcd\)除掉以后,前缀\(\gcd\)会变为\(1\)并且会导致这位之后的\(\gcd\)全部为\(1\)。所以每一位只能选择一次,并且我们从后往前扫肯定比从前往后扫要更优。我们......
  • wzOI 2023.8.31 题解
    2023-09-0115:59:41$$前言$$太菜了,第一题都打成那样了没发现是MST,第三题数据范围没有很仔细看,以为是乱搞(组合之类的)题就直接跳了。不得不说这次比赛题目的一些思路还是挺妙的,一些想法确实我这种成分想不太到。$$A$$$$题意$$给出了\(m\)个可以查询的区间\([L_i,R_i]\)......
  • CF1103C 题解
    2023-09-0514:52:07solution找路径很好找,我们随便跑个dfs树找个深度\(\ge\frac{n}{k}\)的路径输出即可。可是怎么找\(k\)个长度不是\(3\)的倍数的环呢?既然我们跑了dfs树,那么就没有横叉边,对于叶子节点非树边只有返祖边,然后一看这个很奇怪的条件——保证每个点度数大......
  • CF1851 部分题解
    2023-07-3019:35:02前言因为我实在是太菜了,没时间也不会做最后两题,所以这里只有前\(5\)道签到题的题解。之后我有时间看了后两题的题解再来更新吧~A先不用看那么多七七八八的,搞清楚下面几点即可:高度不能相同。高度差得被整除。高度差不能太大。好了,然后就可以\(AC\)......
  • 暑假集训Day19 比赛题解
    2023-08-0516:22:13总结这次打下来,由于T2贪心不够完全,T3模拟\(5\)个时不是最优,T4想到暴力做法但是来不及打,加之全都是捆绑测试点,导致我T2,T3虽然加起来有不少点对了,但是还是判全错,最后也只剩下T1的100。感觉这次前三题也不难,都是可做的,T4的30pts暴力也很白给,但......
  • 暑假集训 Day17 模拟赛题解
    2023-08-0318:18:03前言好家伙,很少完整订正一场比赛,可能是因为这个比赛相对来说确实不难吧(至少正解不难)。总结与反思这场比赛其实没有我想象的那么难,只是觉得题目可能不简单,就没有往简单的思路想,反而是被之前讲过的题疑惑,以为要用到一些很奇特的算法,结果打完以后看了题解再结......
  • UVA10368 题解
    2023-08-0615:18:08solution双倍经验这种有限轮游戏的博弈通常都是有两种状态,必胜态和必败态。对于必胜态,指的是从它可以转移到必败态。对于必败态,指的是从它不论如何只能转移到必胜态。对于每个玩家都采取最优策略的有限游戏,我们通常只需要关注必胜态与必败态之间的转移即......
  • 【题解】AtCoder Regular Contest 162
    A.EkidenRace题目描述:有\(n\)个人参加了往返赛跑,每个人有一个编号\(1\)到\(n\)。已知以下信息:如果按照往路的成绩排序,那么任何两个人的成绩都不相同。同时第\(i\)个人在往路中排名第\(i\)。如果按照往返的成绩排序,那么任何两个人的成绩都不相同。同时第\(i\)个人......
  • P9189 [USACO23OPEN] Custodial Cleanup G 题解
    Description奶牛旅馆可以被看作一个\(N\)个节点\(M\)条边的无向简单图,其中每个房间有一个颜色\(C_i\),以及一个钥匙,颜色为\(S_i\),FJ最初在\(1\)号节点,手上一把钥匙都没有。FJ可以进行无数次以下操作:捡起当前房间的钥匙。(FJ可以同时手持多个钥匙)将部分或全部手......