[关闭]
@2368860385 2020-11-07T03:06:16.000000Z 字数 5354 阅读 175

day7

正睿停课


T1

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15. inline int read() {
  16. int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  17. for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  18. }
  19. const int N = 200100;
  20. const int mod = 1e9 + 7;
  21. LL f[N], ifac[N];
  22. LL ksm(int a,int b) {
  23. LL res = 1;
  24. while (b) {
  25. if (b & 1) res = 1ll * res * a % mod;
  26. a = 1ll * a * a % mod;
  27. b >>= 1;
  28. }
  29. return res;
  30. }
  31. void init(int n) {
  32. f[0] = 1;
  33. for (int i=1; i<=n; ++i) f[i] = 1ll * f[i - 1] * i % mod;
  34. ifac[n] = ksm(f[n], mod - 2);
  35. for (int i=n; i>=1; --i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
  36. }
  37. inline LL C(int n,int m) {
  38. LL t1 = f[n], t2 = ifac[n - m], t3 = ifac[m];
  39. return 1ll * t1 * t2 % mod * t3 % mod;
  40. }
  41. inline LL Calc(int n,int m) {
  42. if (n == m && n == 1) return 1;
  43. return C(n + m - 2, n - 1);
  44. }
  45. int main() {
  46. int n = read(), m = read(), a = read(), b = read();
  47. // init(max(n, m) + 10);
  48. init(n + m);
  49. LL ans = 0;
  50. for (int i=1; i<=(n-a); ++i) {
  51. LL t1 = Calc(i, b);
  52. LL t2 = Calc(n - i + 1, m - b);
  53. (ans += (1ll * t1 * t2 % mod)) %= mod;
  54. }
  55. cout << ans;
  56. return 0;
  57. }
  58. /*
  59. 2 3 1 1
  60. 10 7 3 4
  61. */

T3

推推式子,比较有趣
https://www.cnblogs.com/SovietPower/p/9839063.html

三个的还需要对度数巨大的容斥。

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15. inline int read() {
  16. int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  17. for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  18. }
  19. #define Edge pair<int,int>
  20. const int N = 200005;
  21. const int mod = 1e9 + 7;
  22. int A[N], B[N], deg[N], mi[N];
  23. int n, m, k;
  24. LL ksm(int a,int b) {
  25. LL res = 1;
  26. while (b) {
  27. if (b & 1) res = 1ll * res * a % mod;
  28. a = 1ll * a * a % mod;
  29. b >>= 1;
  30. }
  31. return res;
  32. }
  33. namespace BF1{
  34. int sel[100], vis[100];
  35. LL Answer;
  36. void pd() {
  37. int cnt = 0;
  38. for (int i=1; i<=m; ++i)
  39. if (sel[A[i]] && sel[B[i]]) cnt ++;
  40. if (k == 1) (Answer += cnt) %= mod;
  41. else if (k == 2) (Answer += cnt * cnt) %= mod;
  42. else if (k == 3) (Answer += cnt * cnt * cnt) %= mod;
  43. }
  44. void dfs(int x) {
  45. if (x == n + 1) { pd(); return ; }
  46. sel[x] = 1; dfs(x + 1);
  47. sel[x] = 0; dfs(x + 1);
  48. }
  49. void Main() {
  50. dfs(1); cout << Answer;
  51. }
  52. }
  53. namespace BF2{
  54. void Main() {
  55. LL ans = 0, t = ksm(2, n - 2);
  56. ans = 1ll * t * m % mod;
  57. cout << ans;
  58. }
  59. }
  60. namespace BF3{
  61. void Main() {
  62. LL ans = 1ll * m * mi[n - 2] % mod;
  63. for (int i = 1; i <= m; ++i) {
  64. int d1 = deg[A[i]], d2 = deg[B[i]];
  65. if (n >= 3) ans = (ans + 1ll * (d1 + d2 - 2) * mi[n - 3] % mod) % mod;
  66. // 选这条边的时候,另一条边可能的方案数,(d1-1)+(d2-1)
  67. if (n >= 4) ans = (ans + 1ll * (m - d1 - d2 + 1) * mi[n - 4] % mod) % mod;
  68. // 选这条边的时候的其它边的方案数,m-(d1-1)-(d2-1)-1
  69. }
  70. cout << ans % mod;
  71. }
  72. }
  73. namespace BF4{
  74. void Main() {
  75. LL ans = 0;
  76. for (int i = 1; i <= m; ++i)
  77. for (int j = 1; j <= m; ++j)
  78. for (int k = 1; k <= m; ++k) {
  79. int T[10] = {A[i], B[i], A[j], B[j], A[k], B[k]};
  80. sort(T, T + 6);
  81. int cnt = unique(T, T + 6) - T;
  82. ans = (ans + mi[n - cnt]) % mod;
  83. }
  84. cout << ans % mod;
  85. }
  86. }
  87. int main() {
  88. n = read(), m = read(), k = read();
  89. mi[0] = 1;
  90. for (int i = 1; i <= n; ++i) mi[i] = 1ll * mi[i - 1] * 2 % mod;
  91. for (int i=1; i<=m; ++i) {
  92. A[i] = read(), B[i] = read();
  93. deg[A[i]] ++; deg[B[i]] ++;
  94. }
  95. if (n <= 25) { BF1::Main(); return 0; }
  96. if (k == 1) { BF2::Main(); return 0; }
  97. if (k == 2) { BF3::Main(); return 0; }
  98. if (k == 3) {
  99. if (m <= 300) { BF4::Main(); return 0; }
  100. }
  101. return 0;
  102. }
  103. /*
  104. 4 5 2
  105. 1 2
  106. 2 3
  107. 3 4
  108. 4 1
  109. 2 4
  110. */

摘自http://zhengruioi.com/submission/60594

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<algorithm>
  5. #define mod 1000000007
  6. #define maxn 100010
  7. #define maxm 100010
  8. using namespace std;
  9. int n,m,k,d[maxn],power2[maxn];
  10. struct edge{int u,v;}e[maxm];
  11. void init(){
  12. power2[0]=1;for(int i=1;i<maxn;++i)power2[i]=power2[i-1]*2ll%mod;
  13. memset(d,0,sizeof(d));
  14. scanf("%d%d%d",&n,&m,&k);
  15. for(int i=1;i<=m;++i){
  16. scanf("%d%d",&e[i].u,&e[i].v);
  17. ++d[e[i].u],++d[e[i].v];
  18. }
  19. }
  20. /*
  21. 三条边部分:
  22. s3:三元环个数(三元环计数)
  23. s4:4个点(不含菊花)
  24. t4:至少两处相交(可直接算)
  25. s4=t4-s3*3
  26. s5:5个点
  27. t5:至少一处相交(可直接算)
  28. s5=t5-s4*2-s3*3
  29. s6:三条没有交的边的个数
  30. t6:至少两处没交(可以直接算)
  31. s6=(t6-s5)/3
  32. ans=菊花(可直接算)+s3+s4+s5+s6 (要乘各自的系数)
  33. */
  34. const int size=1000007;
  35. inline bool operator == (const edge &x,const edge &y){return x.u==y.u&&x.v==y.v;}
  36. struct HASH{
  37. vector<edge>tmp[size];
  38. inline void clear(){for(int i=0;i<size;++i)tmp[i].clear();}
  39. inline void insert(int u,int v){
  40. int pos=(1ll*u*maxn+v)%size;edge e=(edge){u,v};
  41. for(int i=0;i<tmp[pos].size();++i)if(tmp[pos][i]==e)return;
  42. tmp[pos].push_back(e);
  43. }
  44. inline bool find(int u,int v){
  45. int pos=(1ll*u*maxn+v)%size;edge e=(edge){u,v};
  46. for(int i=0;i<tmp[pos].size();++i)if(tmp[pos][i]==e)return 1;
  47. return 0;
  48. }
  49. }h;
  50. vector<int>E[maxn];
  51. int count_three_circles(){
  52. h.clear();
  53. for(int i=1;i<=m;++i){
  54. int u=e[i].u,v=e[i].v;
  55. h.insert(u,v),h.insert(v,u);
  56. E[u].push_back(v),E[v].push_back(u);
  57. }
  58. int ans=0;
  59. for(int i=1;i<=m;++i){
  60. int u=e[i].u,v=e[i].v,y=d[u]<d[v]?u:v,x=u^v^y;
  61. for(int j=0;j<E[y].size();++j){
  62. int z=E[y][j];
  63. if(h.find(z,x))++ans;
  64. }
  65. }
  66. return ans/3;
  67. }
  68. int count(){
  69. int ans=0,s3=count_three_circles(),s4,t4=0,s5,t5=0,s6,t6=0;
  70. for(int i=1;i<=n;++i)if(n>=4)ans=(ans+d[i]*(d[i]-1ll)%mod*(d[i]-2)%mod*power2[n-4])%mod;
  71. if(n>=3)ans=(ans+6ll*s3*power2[n-3])%mod;
  72. for(int i=1;i<=m;++i){
  73. int u=e[i].u,v=e[i].v;
  74. t4=(t4+(d[u]-1ll)*(d[v]-1))%mod;
  75. }
  76. s4=(t4-3ll*s3)%mod;if(s4<0)s4+=mod;
  77. if(n>=4)ans=(ans+6ll*s4*power2[n-4])%mod;
  78. for(int i=1;i<=n;++i)t5=(t5+d[i]*(d[i]-1ll)/2%mod*(m-d[i]))%mod;
  79. s5=(t5-s4*2ll-s3*3ll)%mod;if(s5<0)s5+=mod;
  80. if(n>=5)ans=(ans+6ll*s5*power2[n-5])%mod;
  81. for(int i=1;i<=m;++i){
  82. int u=e[i].u,v=e[i].v,x=m-1-(d[u]+d[v]-2);
  83. t6=(t6+x*(x-1ll)/2)%mod;
  84. }
  85. s6=t6-s5;if(s6<0)s6+=mod;
  86. if(n>=6)ans=(ans+2ll*s6*power2[n-6])%mod;
  87. return ans;
  88. }
  89. void solve(){
  90. int ans=0;
  91. for(int i=1;i<=m;++i){
  92. int u=e[i].u,v=e[i].v,du=d[u],dv=d[v];
  93. ans+=power2[n-2];if(ans>=mod)ans-=mod;
  94. int k1;if(k==1)k1=0;if(k==2)k1=1;if(k==3)k1=3;
  95. if(n>=3)ans=(ans+1ll*k1*power2[n-3]*(du+dv-2))%mod;
  96. if(n>=4)ans=(ans+1ll*k1*power2[n-4]*(m-1-(du+dv-2)))%mod;
  97. }
  98. if(k==3){
  99. ans+=count();
  100. if(ans>=mod)ans-=mod;
  101. }
  102. printf("%d\n",ans);
  103. }
  104. int main(){
  105. init();
  106. solve();
  107. return 0;
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注