zoukankan      html  css  js  c++  java
  • 题解 [AGC028D] Chords

    首先, 按照boshi巨佬的说法, 考虑每种联通块的出现次数。如果可以求出, 答案就是每种联通块的出现次数和。

    再按照boshi巨佬的说法, 一种定义联通块长相的方法是用编号最小的点和编号最大的点表示。

    于是设(f[l][r])(l, r)连通且外面的点不连接到里面的点, 里面的所有边都任意连接的方案数。

    由于(l, r)连通不是很好做, 所以就用任意连的方案数目减去连通的方案数目。

    (g[l][r])([l, r])内的点任意连接的方案数目, 有:

    (f[l][r] = g[F(l, r)] - sum f[l][k] imes g[F(k + 1, r)])

    (F(l, r))([l, r])之间没有被强制选的点数。

    那么显然这个方程就是在枚举本区间靠左的连通块的大小。

    容易发现的事实是, 合法的(f[l][r])区间的长度一定是个偶数。 然后(dp)前注意处理一下这个区间是否有连接到外面去的点就好了。

    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    #define R register
    const int N = 600 + 5;
    const int P = 1e9 + 7;
    
    inline int read() {
    	int x = 0, f = 1; char a = getchar();
    	for(; a > '9' || a < '0'; a = getchar()) if(a == '-') f = -1;
    	for(; a >= '0' && a <= '9'; a = getchar()) x = x * 10 + a - '0';
    	return x * f;
    }
    
    int n, m;
    int g[N], fb[N], to[N];
    int f[N][N];
    
    inline int F(int l, int r) {
    	return r - l + 1 + fb[l - 1] - fb[r];
    }
    
    int main() {
    	#ifdef IN
    	//freopen(".in", "r", stdin);
    	//freopen(".out", "w", stdout);
    	#endif
    	n = read(); m = read(); n <<= 1;
    	for(R int i = 1; i <= m; i ++) {
    		int x = read(), y = read();
    		fb[x] = fb[y] = 1;
    		to[x] = y; to[y] = x;
    	}
    	for(R int i = 1; i <= n; i ++) fb[i] += fb[i - 1];
    	g[0] = 1;
    	for(R int i = 2; i <= n; i += 2) g[i] = 1LL * g[i - 2] * (i - 1) % P;
    	int ans = 0;
    	for(R int i = 1; i <= n; i ++) 
    		for(R int j = i; j <= n; j ++)
    			if((j - i) & 1) {
    				bool flg = 0;
    				for(R int k = i; k <= j; k ++)
    					if(to[k] && (to[k] < i || to[k] > j)) flg = 1;
    				if(flg) continue;
    				f[i][j] = g[F(i, j)];
    				for(R int k = i + 1; k < j; k ++)
    					f[i][j] = (f[i][j] - 1LL * f[i][k] * g[F(k + 1, j)] % P + P) % P;
    				ans = (ans + 1LL * f[i][j] * g[F(1, i - 1) + F(j + 1, n)] % P) % P;
    			}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    【BZOJ 2124】【CodeVS 1283】等差子序列
    【BZOJ 1036】【ZJOI 2008】树的统计Count
    【BZOJ 1901】【ZJU 2112】Dynamic Rankings
    【BZOJ 3924】【ZJOI 2015】幻想乡战略游戏
    【BZOJ 4103】【THUSC 2015】异或运算
    【BZOJ 4513】【SDOI 2016】储能表
    【HDU 3622】Bomb Game
    【BZOJ 3166】【HEOI 2013】Alo
    【BZOJ 3530】【SDOI 2014】数数
    【BZOJ 4567】【SCOI 2016】背单词
  • 原文地址:https://www.cnblogs.com/clover4/p/13812681.html
Copyright © 2011-2022 走看看