With several starts, but just one end
欸什么哈夫曼编码原来不是只在初赛出现啊。
赛时忘记了哈夫曼编码的定义,导致没能做出,美美保龄了。
我们先考虑编码的问题,直接就是哈夫曼编码,相信古人的智慧。
但是这题 \(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;
}

浙公网安备 33010602011771号