首页 > 其他分享 >8.13 模拟赛 T3 记录

8.13 模拟赛 T3 记录

时间:2024-08-13 20:38:36浏览次数:15  
标签:tmp int Tree T3 first 8.13 now 模拟 vec

题源

发现 \(v\) 范围很小,有一个基于 \(v\) 的策略就是从 \(1\) 开始往上能合并就合并,这样一定不劣。

于是考虑将序列划分为若干个值相等的段,形如 \((num_{x},x)\),对于一个区间的段,如果有一段比两边相邻的段的数都要小,此时这个段的长度显然不会增加,所以可以直接合并,推平成两边小的那个段的数。

一个段在合并时,如果是 \(2^k\) 可以直接合并 \(k\) 次,不然一定会有剩下来一些没用的,又因为合并时这个数一定不会再增加,所以他会阻止两边合并,于是两边都下取整分成左右两边考虑。(中间加一个分隔符)

用线段树维护一个区间的段的状态,如果区间中有两个分隔符,分隔符中的段就已经可以直接计算了,然后把整一段看成一个分隔符,实现上可以取分隔符为 \((1,inf)\),这样他一定会进行合并。

所以我们线段树中维护的一定是一个至多一个分隔符的,类似上凸的东西,所以每个区间只会维护 \(O(v)\) 个段,两个区间信息合并就是把右区间的每一段插入左区间,复杂度可以接受。

查询区间时把剩下这些段合并即可。

#include <bits/stdc++.h>

using namespace std;

typedef pair<int,int> pii;

const int inf=0x3f3f3f3f;
const int maxn=1e5+5;
struct Tree{
	vector<pii> vec;
	int val;
	Tree(){}
	Tree(vector<pii> vv,int ll){
		vec=vv;
		val=ll;
	}
}tr[maxn<<2];
int a[maxn],lg[maxn];

inline void init(int n){
	lg[0]=-1;
	for(int i=1;i<=n;i++) lg[i]=lg[i>>1]+1;
}

void ins(Tree &now,pii x){
	if(now.vec.empty()){
		now.vec.push_back(x);
		return;
	}
	pii tmp=now.vec.back();
	int lt=(int)now.vec.size();
	if(tmp.first==x.first) now.vec.back().second+=x.second;
	else if(lt>=2&&now.vec[lt-2].first>tmp.first&&tmp.first<x.first){
		now.val=max(now.val,tmp.first+lg[tmp.second]);
		now.vec.pop_back();
		int tt=min(now.vec[lt-2].first,x.first)-tmp.first;
		if(tmp.second<(1<<tt)) ins(now,make_pair(inf,1));
		else if(((tmp.second>>tt)<<tt)==tmp.second) ins(now,make_pair(tmp.first+tt,tmp.second>>tt));
		else{
			ins(now,make_pair(tmp.first+tt,tmp.second>>tt));
			ins(now,make_pair(inf,1));
			ins(now,make_pair(tmp.first+tt,tmp.second>>tt));
		}
		ins(now,x);
	}else now.vec.push_back(x);
}
Tree merge(Tree u,Tree v){
	Tree res=u;
	res.val=max(res.val,v.val);
	for(pii x : v.vec) ins(res,x);
	return res;
}

void pushup(int now){
	tr[now]=merge(tr[now<<1],tr[now<<1|1]);
}
void build(int now,int l,int r){
	if(l==r){
		tr[now].vec.clear();
		tr[now].val=a[l];
		tr[now].vec.push_back(make_pair(a[l],1));
		return;
	}
	int mid=(l+r)>>1;
	build(now<<1,l,mid);
	build(now<<1|1,mid+1,r);
	pushup(now);
}
void update(int now,int l,int r,int x,int v){
	if(l==r){
		tr[now].vec.clear();
		tr[now].val=v;
		tr[now].vec.push_back(make_pair(v,1));
		return;
	}
	int mid=(l+r)>>1;
	if(x<=mid) update(now<<1,l,mid,x,v);
	else update(now<<1|1,mid+1,r,x,v);
	pushup(now);
}
Tree query(int now,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r) return tr[now];
	int mid=(l+r)>>1;
	if(qr<=mid) return query(now<<1,l,mid,ql,qr);
	else if(ql>mid) return query(now<<1|1,mid+1,r,ql,qr);
	else return merge(query(now<<1,l,mid,ql,qr),query(now<<1|1,mid+1,r,ql,qr));
}

Tree ret;

int main(){
	
	freopen("remove.in","r",stdin);
	freopen("remove.out","w",stdout);
	
	int n,q;
	
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	scanf("%d",&q);
	
	init(n);
	build(1,1,n);
	
	while(q--){
		int op,x,y;
		scanf("%d %d %d",&op,&x,&y);
		if(op==2) update(1,1,n,x,y);
		else{
			Tree tmp=query(1,1,n,x,y);
			ret.vec.clear();
			ret.val=tmp.val;
			ins(ret,make_pair(inf,1));
			for(pii x : tmp.vec) ins(ret,x);
			ins(ret,make_pair(inf,1));
			printf("%d\n",ret.val);
		}
	}
	
	return 0;
}

标签:tmp,int,Tree,T3,first,8.13,now,模拟,vec
From: https://www.cnblogs.com/activeO/p/18357648

相关文章

  • 微软NET FrameWork离线运行库+离线安装包合集,一键安装版 微软.NET离线运行库合集2024
     微软.NET离线运行库合集2024最新版是一款专为便捷、高效地管理.NET运行库而设计的工具。这款软件集成了各种版本的.NET运行库,并提供了离线安装的功能,使用户能够在没有网络连接的情况下轻松地安装所需的运行库。该软件的出现极大地简化了.NET开发环境的配置和维护过程。用户可......
  • 8.13今日份作业
     链栈,自己实现一遍,但是节点存储不是整数,存储学生信息(年龄,分数,姓名)三级引用。1、建立学生信息结构体,将data改为学生信息结构体类型。2、循环入栈和入队。链式栈:#include<myhead.h>typedefintmy_int;typedefcharSTR[20];typedefstruct{ STRname;//姓名 my_int......
  • 暑假集训CSP提高模拟17
    A.符号化方法初探看最大数和最小数的绝对值大小,用至多\(n-1\)次让其符号相同,是正数就加前一个数,是负数就倒着加后一个数,最多\(n-2\)次。点击查看代码#include<bits/stdc++.h>constintmaxn=2e5+10;usingnamespacestd;intn,a[maxn],x[maxn],y[maxn],cnt,minn,maxx,......
  • 暑假集训CSP提高模拟19
    A.数字三角形没看到拍列,对着自己造的错样例改半天。填数,由上往下都向左下填,可以保证有解点击查看代码#include<bits/stdc++.h>constintmaxn=550;usingnamespacestd;inta[maxn][maxn],n,flag,cnt,maxx,mi;structlsx{ intx,id; booloperator<(constlsx&a)c......
  • 高性能的 C++ Web 开发框架 CPPCMS + WebSocket 模拟实现聊天与文件传输案例。
    1.项目结构2.config.json{"service":{"api":"http","port":8080,"ip":"0.0.0.0"},"http":{"script":"",&q......
  • 暑假集训csp提高模拟19
    赛时rank5,T1100,T2100,T320,T45T4暴力可过?数据这么水?咋还有失恋舔狗三部曲啊T1数字三角形Fillomino2相对简单的构造题。能向上走就向上走,不能的话往左走,再不能的话就往下走,可以证明一定不会往右走。递归写就行点此查看代码#include<bits/stdc++.h>#include<bi......
  • 字符串查找 - 模拟实现strstr 、BF算法 、 KMP算法
    文章目录前言一、模拟实现库函数strstr二、BF算法三、KMP算法总结前言路漫漫其修远兮,吾将上下而求索。一、模拟实现库函数strstrTips:此处采用利用指针+字符串末尾'\0'的判断,当然你可以利用数组的下标;库函数strstr的原型:char*strstr(constchar*str1,......
  • 『模拟赛』暑假集训CSP提高模拟19
    Rank小挂,还好。A.数字三角形原[CF1517C]Fillomino2锣鼓Rmj炸了所以挂cf链接。签。倒叙考虑,优先向下,到底或者下面有数就向右,有正确性,复杂度\(\mathcal{O(n^2)}\)。水了篇题解,点点推荐rp++。点击查看代码#include<bits/stdc++.h>constintRatio=0;cons......
  • 24/8/12 模拟赛
    hz暑假集训8/12数字三角形CF1517C签到题。题意:小\(D\)给你一个长度为\(n\)的排列\(p\),你需要根据\(p\)构造出一个三角形。该图案需要满足共\(n\)行,第\(i\)行有\(i\)个数,第\(i\)行最后一个数是\(p_i\)。数值\(p_i\)有\(p_i\)个且四联通。几个位置是......
  • 2024华为OD笔试机试 - 模拟目录管理功能 (python/c++/java D卷C卷真题算法)
    华为OD机试(C卷+D卷)2024真题目录(Java&c++&python)题目描述实现一个模拟目录管理功能的软件,输入一个命令序列,输出最后一条命令运行结果。支持命令:创建目录命令:mkdir目录名称,如mkdirabc为在当前目录创建abc目录,如果已存在同名目录则不执行任何操作。此命令无输出......