With several starts, but just one end

QOJ 20726

欸什么哈夫曼编码原来不是只在初赛出现啊。

赛时忘记了哈夫曼编码的定义,导致没能做出,美美保龄了。

我们先考虑编码的问题,直接就是哈夫曼编码,相信古人的智慧。

但是这题 \(1e10\),我们肯定不能直接哈夫曼编码了,考虑压缩状态。不难感觉到,我们所有日志的出现次数的种类一定是根号级别的,证明大概是这样:从数论分块的思想,我们会分成 \(\sqrt n\) 块,不妨假设我们的操作只出现在一个块内,则由于 \(m\) 是根号级别的,所以一块内的日志的出现次数的种类也是根号级别的。然后我们再考虑跨块,显然一次跨块只会增加一种类型。

然后我们就可以处理出来每一种日志的出现次数的出现次数,也就把状态压到了可以跑哈夫曼编码的程度了。当然,本题的哈夫曼编码还是有些不同的,不难意识到一个状态可能是若干程序的汇总,因此我们的状态定义为 \((w,t)\),\(w\) 为权值,是正常的哈夫曼编码会有的,\(tim\) 记的是几个子树的根为这个,然后就可以合并了。

Code

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define File(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout)
#define LL long long
#define ull unsigned long long
#define fi first
#define se second
const int N = 1e6 + 10;
struct node{
	LL pos;
	int flag,val;
};
vector< node > vec;
LL n;
int m;
bool cmp(node x,node y){
	return x.pos < y.pos;
}
vector< pair<LL,LL> > ops;
LL suf[N];
deque<pair<LL,LL> > P,Q;
int main(){
	IOS;
	cin >> n >> m;
	for(LL L=1,R=1;R<=n;){
		vec.push_back({R+1,0,0});
		L = R + 1;
		if(L > n) break;
		R = n / (n / L);
	}
	for(int i=1;i<=m;i++){
		LL l,r;
		cin >> l >> r;
		vec.push_back({l,1,1});
		vec.push_back({r+1,1,-1});
	}
	sort(vec.begin(),vec.end(),cmp);
	LL r,k;
	r = n,k = 0;
	if(!vec.empty() && vec[0].pos > 1)
		ops.push_back({0,vec[0].pos - 1});
	for(int i=0;i<vec.size();i++){
		if(i > 0 && vec[i].pos != vec[i-1].pos){
			ops.push_back({r * k,vec[i].pos - vec[i-1].pos});
			if(vec[i].pos > n) break;
		}
		if(vec[i].flag == 0)
			r = n / vec[i].pos;
		else
			k += vec[i].val;
	}
	sort(ops.begin(),ops.end());
	for(int i=0;i<ops.size();i++){
		if(P.empty()) P.push_back(ops[i]);
		else if(P.back().fi == ops[i].fi)
			P.back().se += ops[i].se;
		else P.push_back(ops[i]);
	}
	LL ans = 0;
	if(n == 1){
		cout << m;
		return 0;
	}
	while(P.size() + Q.size() > 1 || ((Q.size() == 1) && (Q.front().se > 1)) || (P.size() == 1 && (P.front().se > 1))){
		// cout << P.size() << " " << Q.size() << "\n";
		if(P.empty()){
			LL w = Q.front().fi;
			LL tim = Q.front().se;
			Q.pop_front();
			LL p = tim / 2;
			ans += p * 2 * w;
			if(p > 0){
				if(!Q.empty() && w * 2 == Q.back().fi)
					Q.back().se += p;
				else Q.push_back({w*2,p});
			}
			if(tim % 2){
				LL w2 = Q.front().fi;
				Q.front().se -- ;
				ans += w + w2;
				if(Q.front().se == 0) Q.pop_front();
				if(!Q.empty() && w + w2 == Q.back().fi)
					Q.back().se ++ ;
				else Q.push_back({w+w2,1});
			}
		}
		else if(Q.empty()){
			LL w = P.front().fi;
			LL tim = P.front().se;
			P.pop_front();
			LL p = tim / 2;
			ans += p * 2 * w;
			if(p > 0)
				Q.push_back({w*2,p});
			if(tim % 2){
				LL w2;
				if(!P.empty() && !Q.empty() && P.front().fi < Q.front().fi){
					w2 = P.front().fi;
					P.front().se -- ;
					if(P.front().se == 0)
						P.pop_front();
				}
				else if(!P.empty() && Q.empty()){
					w2 = P.front().fi;
					P.front().se -- ;
					if(P.front().se == 0)
						P.pop_front();
				}
				else{
					w2 = Q.front().fi;
					Q.front().se -- ;
					if(Q.front().se == 0)
						Q.pop_front();
				}
				ans += w + w2;
				if(!Q.empty() && w + w2 == Q.back().fi)
					Q.back().se ++ ;
				else
					Q.push_back({w+w2,1});
			}
		}
		else{
			if(P.front().fi < Q.front().fi){
				LL w = P.front().fi;
				LL tim = P.front().se;
				P.pop_front();
				LL p = tim / 2;
				if(p > 0){
					ans += p * 2 * w;
					if(!Q.empty() && w * 2 == Q.back().fi)
						Q.back().se += p;
					else
						Q.push_back({w*2,p});
				}
				if(tim % 2){
					LL w2;
					if(!P.empty() && P.front().fi < Q.front().fi){
						w2 = P.front().fi;
						P.front().se -- ;
						if(P.front().se == 0)
							P.pop_front();
					}
					else{
						w2 = Q.front().fi;
						Q.front().se -- ;
						if(Q.front().se == 0)
							Q.pop_front();
					}
					ans += w + w2;
					if(!Q.empty() && w + w2 == Q.back().fi)
						Q.back().se ++ ;
					else
						Q.push_back({w+w2,1});
				}
			}
			else{
				LL w = Q.front().fi;
				LL tim = Q.front().se;
				Q.pop_front();
				LL p = tim / 2;
				ans += p * 2 * w;
				if(p > 0){
					if(!Q.empty() && w * 2 == Q.back().fi)
						Q.back().se += p;
					else
						Q.push_back({w*2,p});
				}
					
				if(tim % 2){
					LL w2;
					if(!P.empty() && !Q.empty() && P.front().fi < Q.front().fi){
						w2 = P.front().fi;
						P.front().se -- ;
						if(P.front().se == 0)
							P.pop_front();
					}
					else if(!P.empty() && Q.empty()){
						w2 = P.front().fi;
						P.front().se -- ;
						if(P.front().se == 0)
							P.pop_front();
					}
					else{
						w2 = Q.front().fi;
						Q.front().se -- ;
						if(Q.front().se == 0)
							Q.pop_front();
					}
					ans += w + w2;
					if(!Q.empty() && w + w2 == Q.back().fi)
						Q.back().se ++ ;
					else
						Q.push_back({w+w2,1});
				}
			}
		}
	}
	cout << ans << "\n";
	return 0;
}
posted @ 2026-09-29 16:06  WinterXorSnow  阅读(7)  评论(0)    收藏  举报