首页 > 其他分享 >lg9483 [NOI2023] 合并书本

lg9483 [NOI2023] 合并书本

时间:2023-08-03 11:37:10浏览次数:38  
标签:层级 cur int lg9483 lst NOI2023 vector 书本 nv

考虑对合并过程建一棵树。

对于一个点 \(x\),定义 \(a_x\) 表示它向上合并的时候,对答案造成的重量贡献的系数。

定义一个点的层级 \(d_x\) 为它的两个儿子层级的较大值 \(+1\)。我们称 \(d\) 更小的层级为更深的层级。

那么层级为 \(i\) 的非根非叶子节点会对答案造成 \(2^i-1\) 的磨损值贡献。由于非根非叶子节点共有 \(n-2\) 个,可以当成是造成 \(2^i\) 的贡献,最后给答案减掉 \(n-2\) 即可。

考虑这样一个过程:从浅往深(从大往小)扫每一层 \(i\),找出所有 \(d_x<i\) 但 \(d_{fa_x}\geq i\) 的点 \(x\),那么我们只关心可重集 \(S=\{a_x\}\) 以及层数 \(\geq i\) 的点的磨损值贡献之和(记作 \(c\))。

考虑从 \(i\) 层转移到第 \(i-1\) 层时会发生什么,这相当于选择一些叶子把它们分裂成两个叶子。也就是选择 \(S\) 的一个子集 \(T\),对每个 \(t\in T\),将 \(t+1\) 加入到 \(S\),然后令 \(c=2(c+|T|)\)。

然后我们发现两个性质。一个是 \(T\) 一定是 \(S\) 的一个前缀,这是显然的。另一个是对于一个方案,\(|T|\) 从浅到深单调不降,否则我们可以把某个点留到更深的层级再分裂。

于是可以考虑搜索,每次暴力枚举 \(|T|\),一共有划分数种方案,可以获得 75 分。

然后我们发现,对于 \(S\) 相同的状态,只有 \(c\) 最小的那个是有用的,可以 bfs 搜出所有状态。实测 \(n\leq 100\) 的时候只有 \(47575\) 个状态,可以通过。

int lim;
int t,_,n[15],m,i,j,k,a[15][105],vis[500005],lst[500005];
i64 ans,dis[500005];
int ch[500005][105],cnt;
vector<int> seq[500005];
vector<int> f[105];
int qid(vector<int> v)
{
	int x=0,i,len=0;
	vector<int> cur;
	ff(v,it){
		cur.push_back(*it);
		if(!ch[x][*it]){
			ch[x][*it]=++cnt;
			f[cur.size()].push_back(cnt);
			seq[cnt]=cur;
			dis[cnt]=1e18;
		}
		x=ch[x][*it];
	}
	return x;
}
void upd(vector<int> v,i64 c,int l)
{
	int x=qid(v);
	if(dis[x]>c){
		dis[x]=c;lst[x]=l;
	}
	if(dis[x]==c){
		lst[x]=max(lst[x],l);
	}
}
int main()
{
	//cerr<<sizeof(ch)/1048576<<endl;
	read(t);fz1(i,t){read(n[i]);fz1(j,n[i])read(a[i][j]);lim=max(lim,n[i]);}
	upd({0},0,0);
	fz1(_,lim)for(int x:f[_]){
		i64 cur=dis[x]*2;
		vector<int> v=seq[x];
		vector<int> nv=v;
		fz0k(i,v.size()){
			if(x!=1) cur+=2;nv.push_back(v[i]+1);int j=nv.size()-1;
			if(nv.size()>lim) break;
			while(j&&nv[j]<nv[j-1])swap(nv[j],nv[j-1]),j--;
			if(i>=lst[x]) upd(nv,cur,i);
		}
	}
	//cerr<<cnt<<endl;
	fz1(k,t){
		ans=1e18;sort(a[k]+1,a[k]+n[k]+1);
		if(n[k]==1){puts("0");continue;}
		for(int i:f[n[k]]){
			i64 sum=dis[i];
//			cerr<<dis[i]<<endl;ff(seq[i],it) cerr<<*it<<' ';cerr<<endl;
			fz1(j,n[k]) sum+=1ll*a[k][j]*seq[i][n[k]-j];
			ans=min(ans,sum);
		}
		printf("%lld\n",ans-(n[k]-2));
	}
	return 0;
}

标签:层级,cur,int,lg9483,lst,NOI2023,vector,书本,nv
From: https://www.cnblogs.com/asmend/p/17602818.html

相关文章

  • NOI2023 打金记
    扔到cnblogs上。##Day-4最后一场模拟赛,肯定要用力打啊!然而一题不会,呜呜呜。于是开始拼暴力,写了$90+60+60=210$,结果挂成$40+60+60=160$。T1我将题目转化为:对于一个排列,每次只改动三个位置,要求某个数的出现位置,我用了fhq-treap!维护一个桶就好了,不知道自己......
  • NOI2023 题解
    打的太shaber了,于是补补题。D1T1扫描线。首先我们可以容斥一下,答案为被一种操作覆盖到的减去被两种操作覆盖到的加上被三种操作覆盖到的。首先考虑只被一种操作覆盖到的,这很简单,直接上个区间颜色段推平就好了,顺便去了个重。接下来是有被斜线覆盖到的,这样的点数为\(O(nk)\)......
  • P9481 [NOI2023] 贸易 题解
    题目链接题目要求我们求出任意两点间最短路径之和,由于图比较特殊,除树边外只有祖先到其子树内的边,我们首先考虑最短路径有没有什么特殊性质。注意到两点之间的最短路分为一下三种:节点到其祖先的最短路:直接沿着树边向上走即可,否则一定会走多余的边,不是最优。节点到其子树的......
  • NOI2023 后记
    Day1被找规律随机区分\(35\)分。Day2以我现有的水平已经无力回天了,d2T3却还挂了\(35\)分。连队线的边都没碰到,只混到了\(100\)多名的Ag。我不愿回忆这场考试的任何细节,知道寄了就行了。分数是从低往高排的。nfls的众人中,我是第一个上去的。为什么在公布Ag名单时,......
  • 【游记】NOI2023
    前情提要:HE春测+省选rk24,D类选手。前言之前省选游记好像说目标是拿到D类名额+省内高一前\(5\),虽然做到了但是D1T2没分析出很显然的树上做法、D1T3没有想线段树分治以及D2T2选择二分图建模而不是二元组连边都是相当降智操作。结果是导致清北营不过审。中途\(6\)月......
  • NOI2023游记
    想了很久,还是决定写退役记,全都要靠回忆所以应该会漏不少细节。因为已经退役,比赛过程写的比较少,看个乐就行。7.2~7.212号提前到了成都七中,打了两周多的模拟赛。基本都是垫底的,题也补的很少。感觉状态有点差的。保持手感完全靠和学弟duel,学弟好强。7.22报到日。上午大概10......
  • [NOI2023] 深搜
    和考试的时候思路差不多。首先考虑钦定一部分关键点是合法的根,带上容斥系数。对于一条非树边,要求其在任何一个钦定点作为根的时候都不是横叉边。具体而言,对于一个钦定点集合,我们建出钦定点集合的虚树,那么符合条件的非树边有如下几类:不妨先考虑特殊性质\(B\),没有横叉边的情......
  • [NOI2023] 字符串
    对于给出的串\(S\),将其拓展成\(S+\)特殊字符\(+rev(S)\),求出其后缀数组。那么对于一个子串\([l,r]\),合法的必要条件是\(l\)的后缀在后缀数组的排名小于\(r\)的前缀的排名。之所以是必要条件,是因为会记入一些\([l,r]\)是回文串且\(l\)的排名小的情况。具体而言,这......
  • P9482 [NOI2023] 字符串
    P9482[NOI2023]字符串限制长的很像回文串,但是是字典序关系。定睛一看比较的是原串\(s\)的一个后缀的前缀和翻转串\(s'\)的一个后缀的前缀比字典序。直接把\(s'\)拼到\(s\)后面,中间加个分隔符,来一次后缀排序。排名小的后缀字典序比排名大的后缀小。设当前比较的是......
  • 2023 联合省选-PKUSC2023-NOI2023游记
    在这段时间主要在学文化课,没怎么停课,天天暴力拼盘,所以索性合在一起。感觉非常意识流,和OI关系好像也不大。pig嫌我开始写的太短,我积极听取他人建议,加了一车流水账。联赛结束以后就退役了。因为即使NGOI也大概率会被卡“省线”,但还打算参加省选碰碰运气。遂在省选前两周申请一周半......