Part 1
POI 2015 Czarnoksiężnicy okrągłego stołu
大力讨论0到2,神仙DP p=3
CF724F Uniformly Branched Trees
又来一个神仙题
设$dp[i][j][k]$表示以$i$个点中根最大的儿子的大小不超过$j$,根的度数为$k$的方案数,转移是枚举有几个大小为$j$的儿子。
注意这只能解决有根树问题,我们需要定出来一个根来统计。而我们的状态的区别在一开始只体现在最大的儿子,为了不计重我们要找到一类节点使得它最大的儿子的大小较为确定:重心最大的儿子一定不超过$frac{n}{2}$,所以选重心不会计重。如果n是偶数还要考虑有两个重心的情况,分成两半再组合起来即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=1005,M=11; 6 int dp[N][N][M],inv[N],n,m,mod; 7 void Add(int &x,int y) 8 { 9 x+=y; 10 if(x>=mod) x-=mod; 11 } 12 void Pre() 13 { 14 inv[0]=inv[1]=1; 15 for(int i=2;i<=n;i++) 16 inv[i]=mod-1ll*mod/i*inv[mod%i]%mod; 17 memset(dp,-1,sizeof dp); 18 } 19 int DFS(int tot,int mxs,int deg) 20 { 21 mxs=min(mxs,tot-1); 22 int &pt=dp[tot][mxs][deg]; 23 if(~pt) return pt; 24 if(tot==1) return pt=(!deg||deg==m-1); 25 if(!mxs) return pt=0; 26 int ret=DFS(tot,mxs-1,deg),tmp=DFS(mxs,mxs,m-1); 27 for(int i=1,t=1;i*mxs<tot&&i<=deg;i++) 28 { 29 t=1ll*t*(tmp+i-1)%mod*inv[i]%mod; 30 Add(ret,1ll*t*DFS(tot-i*mxs,mxs-1,deg-i)%mod); 31 } 32 return pt=ret; 33 } 34 int main() 35 { 36 scanf("%d%d%d",&n,&m,&mod),Pre(); 37 if(n<=2) printf("1"); 38 else 39 { 40 int ans=DFS(n,(n-1)/2,m); 41 if(n%2==0) 42 { 43 int tmp=DFS(n/2,n/2-1,m-1); 44 Add(ans,1ll*tmp*(tmp+1)%mod*inv[2]%mod); 45 } 46 printf("%d",ans); 47 } 48 return 0; 49 }
CF815D Karen and Cards
先排序以去掉一维限制,剩下两个维度前缀和***搞
一位暴躁的美国老哥认为这太水了并给出了$O(n+p+q+r)$做法
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int N=500005; 6 long long sum,ans,suma[N],sumb[N]; 7 int n,t1,t2,t3,maxa,maxb,maxc,mab[N],mba[N]; 8 struct d 9 { 10 int a,b,c; 11 }cd[N]; 12 bool cmp(d x,d y){return x.c<y.c;} 13 void Maxi(int &x,int y){if(x<y) x=y;} 14 int main() 15 { 16 scanf("%d%d%d%d",&n,&maxa,&maxb,&maxc); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d%d%d",&t1,&t2,&t3); 20 cd[i]=(d){t1,t2,t3}; 21 } 22 sort(cd+1,cd+1+n,cmp); 23 for(int i=1;i<=n;i++) Maxi(mab[cd[i].a],cd[i].b); 24 for(int i=maxa;i;i--) Maxi(mab[i],mab[i+1]); 25 for(int i=1;i<=n;i++) Maxi(mba[cd[i].b],cd[i].a); 26 for(int i=maxb;i;i--) Maxi(mba[i],mba[i+1]); 27 for(int i=1;i<=maxb;i++) sum+=maxa-mba[i]; 28 for(int i=1;i<=maxa;i++) suma[i]=suma[i-1]+maxb-mab[i]; 29 for(int i=1;i<=maxb;i++) sumb[i]=sumb[i-1]+maxa-mba[i]; 30 int p=n,pa=0,pb=0; 31 for(int i=maxc;i;i--) 32 { 33 while(p&&cd[p].c==i) 34 Maxi(pa,cd[p].a+1),Maxi(pb,cd[p].b+1),p--; 35 if(mab[pa]<pb) ans+=1ll*(maxa-pa+1)*(maxb-pb+1); 36 else ans+=sum-suma[pa-1]-sumb[pb-1]; 37 } 38 printf("%lld",ans); 39 return 0; 40 }
CF603E Pastoral Oddities
当做学结论吧 Blog
Part 2
一套被咕咕了的试题
T1 一道计算几何题
计算几何不会选手表示不会
T2 四元环计数 hackerrank Week of Code Jogging Cats
类似三元环计数的做法 器的日报
T3 有向图上的数据结构 hackerrank week of code 25 Dag Queries
对操作分块+整体定期重构,咕咕咕
怕不是作业根本写不动