码迷,mamicode.com
首页 > 其他好文 > 详细

解题:九省联考2018 秘密袭击CoaT

时间:2019-02-20 17:19:42      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:getchar   str   ret   link   ext   联通   包含   不可   printf   

题面

按照*Miracle*的话来说,网上又多了一篇n^3暴力的题解

可能是因为很多猫上树问题虽然很好,但是正解性价比比较低?

我当时在考场上划水的时候手玩了5pts

直接做不可做,转化为统计贡献:$O(n)$枚举每个权值,直接统计第k大大于等于这个权值的联通块个数的和— —这样每个权值x恰会贡献x次。

将所有大于等于当前权值的点点权赋为1,其余点点权赋为零,然后就是$O(n^2)$树形背包:设$dp[i][j]$表示以i为根的子树里选出(新)点权和为j的联通块,且联通块必须包含i自身的方案数。

一些小小的卡常(说实话最慢的点只跑了3s,估计不卡这些都能过,还有好多卡常没上呢):unsigned int,减法取模,不够k个结束(这真的算卡常吗=。=)

技术图片
 1 // luogu-judger-enable-o2
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define uint unsigned int
 7 using namespace std;
 8 const int N=2048;
 9 const uint mod=64123;
10 int n,k,w,t1,t2,cnt,tot;
11 int p[N],noww[2*N],goal[2*N];
12 int val[N],pro[N],siz[N],sze[N];
13 uint ans,dp[N][N];
14 void Read(int &x)
15 {
16     x=0; char ch=getchar();
17     while(!isdigit(ch))
18         ch=getchar();
19     while(isdigit(ch))
20         x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
21 }
22 void Add(uint &x,uint y)
23 { 
24     x+=y;
25     if(x>=mod) x-=mod;
26 }
27 void Link(int f,int t)
28 {
29     noww[++cnt]=p[f];
30     goal[cnt]=t,p[f]=cnt;
31     noww[++cnt]=p[t];
32     goal[cnt]=f,p[t]=cnt;
33 }
34 void DFS(int nde,int fth)
35 {
36     register int i,j,h,g;
37     for(i=0;i<=sze[nde];i++) dp[nde][i]=0;
38     dp[nde][pro[nde]]=1,siz[nde]=pro[nde];
39     for(i=p[nde];i;i=noww[i])
40         if(goal[i]!=fth)
41         {
42             g=goal[i],DFS(g,nde);
43             for(j=siz[nde];~j;j--)
44                 for(h=siz[g];~h;h--)
45                     Add(dp[nde][j+h],dp[nde][j]*dp[g][h]%mod);
46             siz[nde]=siz[nde]+siz[g];
47         }
48     for(i=k;i<=siz[nde];i++) Add(ans,dp[nde][i]);
49 }
50 int main()
51 {
52     register int i,j;
53     Read(n),Read(k),Read(w);
54     for(i=1;i<=n;i++) Read(val[i]);
55     for(i=1;i<n;i++) Read(t1),Read(t2),Link(t1,t2);
56     for(i=1;i<=w;tot=0,i++)
57     {
58         for(j=1;j<=n;j++) pro[j]=val[j]>=i,tot+=pro[j];
59         if(tot<k) printf("%u",ans),exit(0); DFS(1,0),swap(siz,sze); 
60     }    
61     printf("%u",ans);
62     return 0;
63 }
View Code

 

解题:九省联考2018 秘密袭击CoaT

标签:getchar   str   ret   link   ext   联通   包含   不可   printf   

原文地址:https://www.cnblogs.com/ydnhaha/p/10407663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!