2023牛客暑期多校训练营8-C Clamped Sequence II

2023牛客暑期多校训练营8-C Clamped Sequence II

https://ac.nowcoder.com/acm/contest/57362/C

文章目录

  • [2023牛客暑期多校训练营8-C Clamped Sequence II](#2023牛客暑期多校训练营8-C Clamped Sequence II)

题意

解题思路

先考虑不加紧密度的情况,要支持单点修改,整体查询,可以用值域线段树来求。设 t r e e x . n u m treex.num treex.num表示数值在 l , r l,r l,r区间的数的个数, t r e e x . s u m treex.sum treex.sum表示数值在 l , r l,r l,r区间的数的总和, t r e e x . a n s treex.ans treex.ans表示数值在 l , r l,r l,r区间的数的紧密度,结合下图,可以求得转移式:

n u m x = n u m l s o n + n u m r s o n s u m x = n u m l s o n + s u m r s o n a n s x = a n s l s o n + a n s r s o n + s u m r s o n × n u m l s o n − s u m l s o n × n u m r s o n num_x=num_{lson}+num_{rson}\\ sum_x=num_{lson}+sum_{rson}\\ ans_x=ans_{lson}+ans_{rson}+sum_{rson}\times num_{lson}-sum_{lson}\times num_{rson} numx=numlson+numrsonsumx=numlson+sumrsonansx=anslson+ansrson+sumrson×numlson−sumlson×numrson

此时我们加入紧凑的设定,对于每一对确定的 l , r l,r l,r我们都可以算出此时的答案:
a n s w e r = a n s l , r + s u m l , r × ( n u m 1 , l − 1 − n u m r + 1 , n ) + ( n u m 1 , l − 1 + n u m l , r ) × n u m r + 1 , n − ( n u m r + 1 , n + n u m l , r ) × n u m 1 , l − 1 answer=ans_{l,r}+sum_{l,r}\times(num_{1,l-1}-num_{r+1,n})+(num_{1,l-1}+num_{l,r})\\ \times num_{r+1,n}-(num_{r+1,n}+num_{l,r})\times num_{1,l-1} answer=ansl,r+suml,r×(num1,l−1−numr+1,n)+(num1,l−1+numl,r)×numr+1,n−(numr+1,n+numl,r)×num1,l−1

根据出题人所说,该答案是严格单峰的,所以可以用三分求解,但经过我实践却不太像,需要将三分的范围约束在最中间的数 ± d \pm d ±d再加上左右游移 2 ∼ 3 2\sim 3 2∼3个数,大致能求出正确答案。

代码

复制代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5,M=1e6+5;
ll n,a[N],b[M],q;
struct node{
	ll num,l,r;
	ll sum,ans;
	node operator +(const node a){
		node t;
		t.num=num+a.num,t.sum=sum+a.sum;
		t.ans=num*a.sum-sum*a.num+ans+a.ans;
		t.l=l,t.r=a.r;
		return t;
	}
};
struct tree{
	node tr[M<<2];
	void build(int res,int l,int r){
		tr[res].l=l,tr[res].r=r;
		if(l==r){
			tr[res].num=b[l],tr[res].sum=b[l]*l;
			return;
		}
		int mid=l+r>>1;
		build(res<<1,l,mid);
		build(res<<1|1,mid+1,r);
		tr[res]=tr[res<<1]+tr[res<<1|1];
	}
	void add(int res,int x,ll d){
		int l=tr[res].l,r=tr[res].r;
		if(l==r&&l==x){
			tr[res].sum+=d*l;
			tr[res].num+=d;
			return;
		}
		int mid=l+r>>1;
		if(x<=mid)add(res<<1,x,d);
		else add(res<<1|1,x,d);
		tr[res]=tr[res<<1]+tr[res<<1|1];
		return;
	}
	node query(int res,int x,int y){
		if(x>y)return node{0,0,0,0,0};
		int l=tr[res].l,r=tr[res].r;
		if(x<=l&&y>=r){
			return tr[res];
		}
		int mid=l+r>>1;
		if(y<=mid)return query(res<<1,x,y);
		if(x>mid)return query(res<<1|1,x,y);
		return query(res<<1,x,y)+query(res<<1|1,x,y);
	}
    int kth(int id,int l,int r,int k)
    {
        if(l==r) return l;
        int mid=l+r>>1;
        if(tr[id<<1].num>=k) return kth(id<<1,l,mid,k);
        else return kth(id<<1|1,mid+1,r,k-tr[id<<1].num);
    }
}t;
ll f(int l,int d){
	int r=l+d;
    node p=t.query(1,l,r);
	ll num1=p.num,ans1=p.ans,sum1=p.sum;
	ll numl=t.query(1,1,l-1).num,numr=t.query(1,r+1,M-1).num;
	return ans1-numl*(numr+num1)*l+numr*(numl+num1)*r+sum1*(numl-numr);
}
ll work(int d){
    int k=t.kth(1,1,M-1,n+1>>1);
	int l=max(1,k-d),r=min(M-1,k+d);
	ll ma=0;
	while(l+2<=r){
		int mi1=(r-l)/3+l,mi2=r-(r-l)/3;
        ll ma1=f(mi1,d),ma2=f(mi2,d);
		ma=max(ma,max(ma1,ma2));
		if(ma1>=ma2)r=mi2-1;
		else l=mi1+1;
	}
	
	for(int i=l;i<=r;i++)
	ma=max(ma,f(i,d));
	return ma;
}
int main(){
    ios::sync_with_stdio(false);
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i],b[a[i]]++;
	t.build(1,1,M-1);
	while(q--){
		int op;
		cin>>op;
		if(op==1){
			int x,d;
			cin>>x>>d;
			t.add(1,a[x],-1);
			t.add(1,d,1);
			a[x]=d;
		}else{
			int d;
			cin>>d;
			cout<<work(d)<<'\n';
		}
	}
}
相关推荐
Evand J23 分钟前
【电机滤波例程1】PMSM永磁同步电机转速与位置估计,MATLAB程序:标准无迹卡尔曼滤波、模型说明与仿真验证
算法·matlab·电机·ekf·负载·卡尔曼滤波
lhbweilai27 分钟前
深挖FreeRTOS内核实现(二)
c语言·汇编·stm32·单片机
杨丰玮41833 分钟前
C语言核心语法
java·c语言·开发语言·学习方法
打码的老程是远篁41 分钟前
手把手教你玩转大模型——3. Transformer 的位置编码——模型怎么知道谁在前,谁在后?
人工智能·算法
嘎嘎风42 分钟前
MiniMind 学习笔记之 06 一张图、一百行:MiniMind 的骨架
算法·源码
用户7341681035481 小时前
只盯被动响应做状态监测?论“控制信号”在变工况故障诊断中的重要作用
算法
Ivanqhz1 小时前
MQA、GQA、稀疏/滑动窗口注意力及混合范式
人工智能·算法·机器学习
罗湖老棍子1 小时前
荒岛野人(信息学奥赛一本通- P1637)(洛谷-P2421)
算法·数论·枚举·裴蜀定理·扩展欧几里得·扩展中国剩余定理
朝朝辞暮i1 小时前
C++ 第 40 章:ROS2 Publisher + Timer + Subscriber + Callback + Executor 完整闭环
开发语言·c++·算法·ros2
400分1 小时前
具身智能系列之从零到「机械臂会放试管」:π0.5 VLA 真机部署完全指南【第一节】
算法