标签:dfs oid 一个 spl space 就是 close head col
还说啥啊,这就是不行啊。
数学题,组合排列,我连一点思路都没有。
真的不会。
容斥,这是能想到的,但完全不会容斥啊。
先挂上一篇DeepInC博客,写的很好。
我们先考虑总体不合法的地方至少有0个的情况,情况是$C_{m-1}^{n-1}$,裸的挡板法,问题其实就是在$n$个里面插入$m-n$个数,可以为空的方案数,可以表示 为$C_{n+(m-n)-1}^{m-n}$,可以化简,不再缀述。
然后再去看DeepInC博客就好了,我只简单的给自己提醒一下。
公式$C_n^i * C_{m-i*k-1}^{n-1}$
然后为什么要减去$i*k$呢,意思是把分给$i$个$k$个元素,让他们到达最大值,然后开始分剩下的元素,一定能使这$i$个超限,这也做到了“至少”,然后就挡板法解决了。
小弟不才。
1 #include<cstdio> 2 #include<iostream> 3 #define LL long long 4 #define HZOI std 5 using namespace HZOI; 6 const int mod=998244353; 7 const int N=1e7+3; 8 int n,m,k,p; 9 LL Finv[N],inv[N],F[N]; 10 LL ans,ooo; 11 inline void Init(); 12 inline LL Comb(int ,int ); 13 int main() 14 { 15 // freopen("1.out","w",stdout); 16 scanf("%d%d%d",&n,&m,&k); 17 Init(); 18 if (n>m) {puts("0");return 0;} 19 ooo=1; 20 for (int i=0; i<=n and m-i*k-1>=0; ++i,ooo=-ooo) 21 ans=(ans+ooo*Comb(n,i)*Comb(m-i*k-1,n-1)%mod+mod)%mod; 22 printf("%lld\n",(ans+mod)%mod); 23 } 24 inline LL Comb(int x,int y) 25 { 26 if (y>x) return 0; 27 return F[x]*1ll*Finv[y]%mod*Finv[x-y]%mod; 28 } 29 inline void Init() 30 { 31 inv[1]=1; 32 for (int i=2; i<=m; ++i) 33 inv[i]=(mod-mod/i)*1ll%mod*inv[mod%i]%mod; 34 Finv[0]=F[0]=1; 35 for (int i=1; i<=m; ++i) 36 F[i]=F[i-1]%mod*i%mod, 37 Finv[i]=Finv[i-1]%mod*inv[i]%mod; 38 }
一道裸的语文题。
乍一看题,看不懂,那种不知道要干嘛的看不懂,样例不会玩,$Dfs$不会打,心情十分激动。
然后,就按着错的思路想了半天。
很难受。
实际上一个点,它所能到达的那一条链上的点都不能同时炸。然后呢,发现一个很显然的性质:一个环,需要炸的次数就是它的大小。然后这道题就没了。
考试的时候就知道一个缩点。缩点之后要干啥?不知道,就会瞎缩,然后就懵了。
然后一个拓扑,从入度为0的点开始搜,搜到最后找到最长链,$ok$了。
小弟不才。
1 #include<cstdio> 2 #include<cstring> 3 #define HZOI std 4 using namespace HZOI; 5 const int N=1e7+3; 6 int n,m,ans; 7 int tt,first[N],vv[N<<1],nx[N<<1]; 8 int TT,First[N],VV[N<<1],Next[N<<1]; 9 int num,tot,stc[N<<1],dfn[N],low[N],be[N],sz[N]; 10 int head,tail,q[N],du[N],vis[N],dep[N]; 11 inline void Add(int ,int ); 12 inline void NewAdd(int ,int ); 13 void Tarjan(int ); 14 inline void Solve(); 15 inline int read(); 16 inline int min(int a,int b) {return a<b?a:b;} 17 inline int max(int a,int b) {return a>b?a:b;} 18 int main() 19 { 20 n=read(),m=read(); 21 for (int i=1,x,y; i<=m; ++i) 22 { 23 x=read(),y=read(); 24 Add(x,y); 25 } 26 for (int i=1; i<=n; ++i) 27 if (!dfn[i]) 28 Tarjan(i); 29 for (int i=1; i<=n; ++i) 30 for (int j=first[i]; j; j=nx[j]) 31 { 32 if (be[i]==be[vv[j]]) continue; 33 NewAdd(be[i],be[vv[j]]),++du[be[vv[j]]]; 34 } 35 memset(vis,0,sizeof(vis)); 36 Solve(); 37 printf("%d\n",ans); 38 } 39 inline void Solve() 40 { 41 head=tail=0; 42 for (int i=1; i<=num; ++i) 43 if (!du[i]) 44 q[++tail]=i,vis[i]=1,dep[i]=sz[i]; 45 while (head^tail) 46 { 47 int x=q[++head]; 48 for (int i=First[x]; i; i=Next[i]) 49 { 50 int ver=VV[i]; 51 if (vis[ver]) continue; 52 dep[ver]=max(dep[ver],dep[x]+sz[ver]); 53 if (!(--du[ver])) q[++tail]=ver,vis[ver]=1; 54 } 55 ans=max(ans,dep[x]); 56 } 57 } 58 void Tarjan(int k) 59 { 60 dfn[k]=low[k]=++tot; 61 vis[k]=1; 62 stc[++tail]=k; 63 for (int i=first[k]; i; i=nx[i]) 64 { 65 int ver=vv[i]; 66 if (!dfn[ver]) 67 { 68 Tarjan(ver); 69 low[k]=min(low[k],low[ver]); 70 } 71 if (vis[ver]) low[k]=min(dfn[ver],low[k]); 72 } 73 if (dfn[k]==low[k]) 74 { 75 int to; 76 ++num; 77 do 78 { 79 to=stc[tail--]; 80 be[to]=num; 81 vis[to]=0; 82 ++sz[num]; 83 }while (to^k); 84 } 85 } 86 inline void NewAdd(int u,int v) 87 { 88 VV[++TT]=v,Next[TT]=First[u],First[u]=TT; 89 } 90 inline void Add(int u,int v) 91 { 92 vv[++tt]=v,nx[tt]=first[u],first[u]=tt; 93 } 94 inline int read() 95 { 96 int nn=0;char ch=getchar(); 97 while (ch<‘0‘ or ch>‘9‘) ch=getchar(); 98 while (ch>=‘0‘ and ch<=‘9‘) nn=(nn<<3)+(nn<<1)+(ch^48),ch=getchar(); 99 return nn; 100 }
标签:dfs oid 一个 spl space 就是 close head col
原文地址:https://www.cnblogs.com/LH-Xuanluo/p/11330374.html