cf600E

来源:互联网 发布:哪项不是数据定义语言 编辑:程序博客网 时间:2024/06/07 17:16

一开始用sb方法,时间没超然而内存爆了,之后又换了操作,启发式合并可证明最坏情况是合并的复杂度一共是nlognlogn的复杂度。map还是好容易在dfs里面炸内存啊。然而他swap两个map和swap两个map的下标最后的时间差别只有一点点。据说swap(map[1],map[2])是只交换指针的,不用遍历整个map[1],map[2]种的元素,神奇。

#include<cstdio>#include<cstring>#include<algorithm>#include<set>#include<map>#define maxl 100010using namespace std;int n,cnt;int col[maxl],ehead[maxl];int dy[maxl];long long ans[maxl];struct ed{int to,nxt;} e[maxl<<1];map <int,int> mp[maxl];map <int,long long> sum[maxl];map <int,int> :: iterator it1,it2;inline int read(){int x=0;char ch=getchar();while(ch<'0' || ch>'9') ch=getchar();while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x;}void prework(){/*memset(ehead,0,sizeof(ehead));for(int i=1;i<=n;i++)mp[i].clear();*/for(int i=1;i<=n;i++)col[i]=read(),dy[i]=i,mp[i][col[i]]=1,sum[i][1]=col[i];int u,v;cnt=0;for(int i=1;i<=n-1;i++){u=read();v=read();e[++cnt].to=v;e[cnt].nxt=ehead[u];ehead[u]=cnt;e[++cnt].to=u;e[cnt].nxt=ehead[v];ehead[v]=cnt;}}void dfs(int u,int fa){int v;for(int i=ehead[u];i;i=e[i].nxt){v=e[i].to;if(v!=fa){dfs(v,u);if(mp[dy[u]].size()<mp[dy[v]].size())swap(dy[u],dy[v]);for(it1=mp[dy[v]].begin();it1!=mp[dy[v]].end();++it1){sum[dy[u]][mp[dy[u]][(*it1).first]]-=(*it1).first;mp[dy[u]][(*it1).first]+=(*it1).second;sum[dy[u]][mp[dy[u]][(*it1).first]]+=(*it1).first;}}}ans[u]=(*sum[dy[u]].rbegin()).second;}void mainwork(){dfs(1,0);}void print(){for(int i=1;i<=n;i++)printf("%I64d ",ans[i]);printf("\n");}int main(){while(~scanf("%d",&n)){prework();mainwork();print();}return 0;}


原创粉丝点击