CF1009E-Dominant Indices题解
CF1009E-被成功卡空间有感
垃圾回收就是个垃圾((
根据某些帖子的说法好像可以利用压缩trie把空间压到线性,但是起码我写的垃圾回收还是卡不过去(不知道是写错了还是怎么回事,空间跟不开内存池并无太大区别...),对于test131的数据(一条1e6长的链),洛谷关于此题的所有线段树合并的题解好像都卡不过去。。。
所以线段树合并的空间复杂度是O(nlogn),在512mb的题目中1e6仍然卡不过去,,这时候就不要作死写线段树合并了,,
另,主席树也没法维护两个版本的差值的最大值点,,所以这波先写了两个错误写法。。。
Upd:
终于a了这个题了,,使用的是dsu on tree+线段树维护
树上启发式合并是O(nlogn)的复杂度
再套一个普通线段树,总时间复杂度应该是两个log的,但这题不卡时间,,
树上启发式合并跑出每个点的子树的深度集合,这个集合用线段树来维护,每次我们要询问这个点的子树所有点同一深度最多的深度值,可以用线段树维护每个深度点的数量的最大值以及对应的深度。
#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
#define debugg(x) cout<<#x<<'='<<x<<endl;
#define debug1(x,y,z) cout<<#x<<' '<<x<<' '<<#y<<' '<<y<<' '<<#z<<' '<<z<<endl;
#define debug cout<<endl<<"********"<<endl;
#define ll long long
#define ull unsigned long long
#define ld long double
#define itn int
#define pii pair<int,int>
#define rep(I, A, B) for (int I = (A); I <= (B); ++I)
#define dwn(I, A, B) for (int I = (A); I >= (B); --I)
#define mod (ll)(19940417)
#define mid ((lo+ro)>>1)
void fre(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
void fc(){fclose(stdin);fclose(stdout);}
inline ll ccin(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline void cou(ll x){
if(x<0) putchar('-'),x=-x;
if(x>9) cou(x/10);
putchar(x%10+'0');
}
const int maxn=1e6+10;
const ll inf=0x7fffffff;
int n,m;
struct node{
int fat;int dep;int siz;int zson;
}all[maxn];
struct xnode{
int lo;int ro;int zhi;int mbiao;
}tre[maxn*4];
int dfn[maxn],cntnum,rdfn[maxn],totd;
int cntdep[maxn];
int ans[maxn];
vector<int> yuan[maxn];
void pushup(int now,int lo,int ro){
if(tre[lo].zhi!=tre[ro].zhi){
tre[now].mbiao=(tre[lo].zhi>tre[ro].zhi)?tre[lo].mbiao:tre[ro].mbiao;
tre[now].zhi=(tre[lo].zhi>tre[ro].zhi)?tre[lo].zhi:tre[ro].zhi;
}
else tre[now].mbiao=tre[lo].mbiao,tre[now].zhi=tre[lo].zhi;
}
void build(int now,int lo,int ro){
tre[now].lo=lo;tre[now].ro=ro;
if(lo==ro) return;
build(now*2,lo,mid);
build(now*2+1,mid+1,ro);
}
void updx(int now,int pos,int zhi){
if(tre[now].lo==tre[now].ro&&tre[now].lo==pos){
tre[now].zhi+=zhi;tre[now].mbiao=tre[now].lo;
return;
}
if(tre[now].ro<pos||tre[now].lo>pos) return;
int mi=(tre[now].lo+tre[now].ro)/2;
if(pos<=mi) updx(now*2,pos,zhi);
else updx(now*2+1,pos,zhi);
pushup(now,now*2,now*2+1);
}
void erase(int now){
for(int i=dfn[now];i<=dfn[now]+all[now].siz-1;i++){
updx(1,all[rdfn[i]].dep,-1);
}
}
void upd(int now){
for(int i=dfn[now];i<=dfn[now]+all[now].siz-1;i++){
updx(1,all[rdfn[i]].dep,1);
}
}
void dfs(int now,int fa){
all[now].dep=all[fa].dep+1;
totd=max(totd,all[now].dep);
all[now].fat=fa;all[now].siz=1;
dfn[now]=++cntnum;
rdfn[cntnum]=now;
for(int i=0;i<yuan[now].size();i++){
int v=yuan[now][i];
if(v==fa) continue;
dfs(v,now);
all[now].siz+=all[v].siz;
if(all[all[now].zson].siz<=all[v].siz) all[now].zson=v;
}
}
void dfs1(int now,int ifz){
for(int i=0;i<yuan[now].size();i++){
int v=yuan[now][i];
if(v==all[now].fat||v==all[now].zson) continue;
dfs1(v,0);
}
if(all[now].zson) dfs1(all[now].zson,1);
for(int i=0;i<yuan[now].size();i++){
int v=yuan[now][i];
if(v==all[now].fat||v==all[now].zson) continue;
upd(v);
}
updx(1,all[now].dep,1);
ans[now]=tre[1].mbiao;
if(!ifz) erase(now);
}
int main(){
ios;cin>>n;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
yuan[u].push_back(v);
yuan[v].push_back(u);
}
dfs(1,0);
build(1,1,totd);
dfs1(1,0);
for(int now=1;now<=n;now++) cout<<ans[now]-all[now].dep<<endl;
return 0;
}
/*
12
1 2
1 3
3 6
3 7
2 4
4 8
4 5
5 10
5 9
5 11
5 12
*/

浙公网安备 33010602011771号