1 条题解
-
0
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1005; const int M=1e7+5; int Head[N],vet[N<<1],Next[N<<1]; int p[N],x[N],y[N],fa[N],f[N],g[N],deg[N],pos[N],vis[N],siz[N],dis[N]; ll vec[M],U[M],D[M]; int L,tp,tq,edgenum,len,res; int Find(int u){ return fa[u]==u?u:fa[u]=Find(fa[u]); } void gen1(){ //第一种生成方法 for (int i=1; i<=1000; i++) p[i]=i; random_shuffle(p+1,p+1+1000); for (int i=2; i<=1000; i++) x[i-1]=p[rand()%(i-1)+1],y[i-1]=p[i]; } void gen2(){ //第二种生成方法 for (int i=1; i<=1000; i++) p[i]=i; random_shuffle(p+1,p+1+1000); for (int i=2; i<=1000; i++) x[i-1]=p[i/2+rand()%(i-i/2)],y[i-1]=p[i]; } void gen3(){ //第三种生成方法 for (int i=1; i<=1000; i++) fa[i]=i; int cnt=0; while (cnt<999){ int u=rand()%1000+1,v=rand()%1000+1; if (Find(u)!=Find(v)){ cnt++; x[cnt]=u,y[cnt]=v; fa[Find(u)]=Find(v); } } } void gen4(){ //第四种生成方法,随机prufer序列 for (int i=1; i<=998; i++) p[i]=rand()%1000+1; set<int> s; memset(vis,0,sizeof(vis)); for (int i=1; i<=998; i++) vis[p[i]]++; for (int i=1; i<=1000; i++) if (!vis[i]) s.insert(i); for (int i=1; i<=998; i++){ int t=*s.begin(); x[i]=t,y[i]=p[i]; s.erase(t); vis[p[i]]--; if (!vis[p[i]]) s.insert(p[i]); } int t=*s.begin(); s.erase(t); x[999]=t,y[999]=*s.begin(); } void gen(int t){ if (t==1) gen1(); if (t==2) gen2(); if (t==3) gen3(); if (t==4) gen4(); } void dfs(int u, int F){ f[u]=1,g[u]=0; for (int e=Head[u]; e; e=Next[e]){ int v=vet[e]; if (v==F) continue; dfs(v,u); if (f[v]+1>f[u]) g[u]=f[u],f[u]=f[v]+1; else if (f[v]+1>g[u]) g[u]=f[v]+1; } } void solve1(){ int ans=0; dfs(1,0); for (int i=1; i<=1000; i++) ans=max(ans,f[i]+g[i]); vec[++len]=ans; } void solve2(){ int ans=0; for (int i=1; i<=1000; i++) ans+=(deg[i]==2); vec[++len]=ans; } void solve10(){ int ans=0; dfs(1,0); for (int i=1; i<=1000; i++) ans+=f[i]+g[i]; vec[++len]=ans; } void solve14(){ int ans=0; dfs(1,0); for (int i=1; i<=1000; i++) ans+=f[i]*f[i]+g[i]*g[i]; vec[++len]=ans/50; } void solve3(){ int ans=0; for (int i=1; i<=1000; i++) ans+=deg[i]*deg[i]; vec[++len]=ans; } void solve4(){ ll ans=0,sum=0; for (int i=1; i<=1000; i++) sum+=deg[i]; for (int i=1; i<=1000; i++) ans+=1ll*(1000*deg[i]-sum)*(1000*deg[i]-sum); vec[++len]=ans/100000; } void dfs1(int u, int f){ siz[u]=1; int mx=0; for (int e=Head[u]; e; e=Next[e]){ int v=vet[e]; if (v==f) continue; dfs1(v,u); siz[u]+=siz[v]; mx=max(mx,siz[v]); } mx=max(mx,1000-siz[u]); if (mx<res) res=mx; } int dfs2(int u, int f){ siz[u]=1; int mx=0,sum=0; for (int e=Head[u]; e; e=Next[e]){ int v=vet[e]; if (v==f) continue; sum+=dfs2(v,u); siz[u]+=siz[v]; mx=max(mx,siz[v]); } mx=max(mx,1000-siz[u]); return sum+mx; } void solve5(){ dfs1(1,0); int ans=0; for (int i=1; i<=1000; i++) ans+=siz[i]; vec[++len]=ans; } void solve6(){ dfs1(1,0); int ans=0; for (int i=1; i<=1000; i++) ans+=siz[i]*siz[i]; vec[++len]=ans; } void solve7(){ dfs1(1,0); ll ans=0,sum=0; for (int i=1; i<=1000; i++) sum+=siz[i]; for (int i=1; i<=1000; i++) ans+=1ll*(1000*siz[i]-sum)*(1000*siz[i]-sum); vec[++len]=ans/100000; } void solve8(){ res=1e9; dfs1(1,0); vec[++len]=res; } void solve9(){ vec[++len]=dfs2(1,0); } double dfs3(int u, int f){ siz[u]=1; double sum=0; for (int e=Head[u]; e; e=Next[e]){ int v=vet[e]; if (v==f) continue; sum+=dfs3(v,u); siz[u]+=siz[v]; } sum+=log2(siz[u])+log2(1001-siz[u]); return sum; } void solve11(){ vec[++len]=dfs3(1,0); } void solve12(){ queue<int> que; int ans=0; for (int i=1; i<=1000; i++) if (deg[i]==1) que.push(i),dis[i]=1; else dis[i]=1e9; while (!que.empty()){ int u=que.front(); que.pop(); for (int e=Head[u]; e; e=Next[e]){ int v=vet[e]; if (dis[v]!=1e9) continue; deg[v]--; if (deg[v]==1) que.push(v),dis[v]=dis[u]+1; } ans+=dis[u]*dis[u]; } vec[++len]=ans; } void solve13(){ int ans=0; for (int i=1; i<=1000; i++) ans+=(deg[i]==1); for (int i=1; i<=1000; i++) ans-=(deg[i]==2); vec[++len]=ans; } void solve(int t){ if (t==1) solve1(); //直径 if (t==2) solve2(); //二度点个数 if (t==3) solve3(); //deg的平方和 if (t==4) solve4(); //deg的方差 if (t==5) solve5(); //以1为根的子树大小之和 if (t==6) solve6(); //以1为根的子树大小的平方和 if (t==7) solve7(); //以1为根的子树大小的方差 if (t==8) solve8(); //重心的最大子树大小 if (t==9) solve9(); //我也不知道这个是在干啥。。。 if (t==10) solve10(); //每个点子树中最长链+次长链的长度 if (t==11) solve11(); //每个点各个子树大小的对数之和 if (t==12) solve12(); //每个点到最远一度点距离的平方和 if (t==13) solve13(); //一度点个数-二度点个数 if (t==14) solve14(); //每个点子树中最长链平方+次长链平方 } inline void addedge(int u, int v){ edgenum++; vet[edgenum]=v; Next[edgenum]=Head[u]; Head[u]=edgenum; } int main(){ scanf("%d%d%d",&L,&tp,&tq); //L为随机撒点的个数,tp为生成树的方法(标号与题目中相同),tq为尝试的不同函数的编号 signed a[5000],sum; for (int i=0; i<5000; i++) sum+=a[i]; srand(sum); for (int o=1; o<=L; o++){ gen(tp); memset(deg,0,sizeof(deg)); memset(Head,0,sizeof(Head)); edgenum=0; for (int i=1; i<1000; i++){ addedge(x[i],y[i]),addedge(y[i],x[i]); deg[x[i]]++,deg[y[i]]++; } solve(tq); if (o%1000==0) printf("==>%d times\n",o); //表示目前撒了多少样本点了 } ll mn=1e18,mx=-1e18; for (int i=1; i<=L; i++) mx=max(mx,vec[i]),mn=min(mn,vec[i]); printf("%lld %lld\n",mn,mx); //特征值的范围 ll P=0; scanf("%lld",&P); //给出均分[min,max]的长度 ll cur=mn; int tot=0; while (cur<=mx){ D[++tot]=cur; U[tot]=(cur+P-1>=mx?mx:cur+P-1); cur+=P; } for (int i=1; i<=L; i++) for (int j=tot; j>=1; j--) if (vec[i]<=U[j] && vec[i]>U[j-1]){ pos[j]++; break; } for (int i=1; i<=tot; i++) printf("%lld %lld %d\n",D[i],U[i],pos[i]); //表示特征值在[D,U]中的样本点个数 return 0; }
- 1
信息
- ID
- 208
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 14
- 已通过
- 0
- 上传者