zoukankan      html  css  js  c++  java
  • Atcoder Grand Contest 018 E

    Atcoder Grand Contest 018 E - Sightseeing Plan

    枚举从第二个矩形的 ((x_1,y_1)) 进入,((x_2,y_2)) 出来,那么中间可以选的点的数量是 (x_2+y_2-x_1-x_2+1) ,也就是说对于每一条合法路线,从 ((x_1,y_1)) 进入的贡献为 (-x_1-x_2) ,从 ((x_2,y_2)) 出来的贡献为 (x_2+y_2+1) ,枚举一下第二个矩形边界上的点,我们只需要分别计算某个点到第一个矩形的方案数和到第三个矩形的方案数即可。

    考虑一个点到一个矩形的方案数是有一个组合意义转化的。

    (F(x,y)) 表示 ((0,0))((x, y)) 的方案数,有以下结论:

    [sum_{i=0}^yF(x,i) =F(x,y+1) \ sum_{i=0}^xsum_{j=0}^y F(i,j)=F(x+1,y+1)-1 ]

    组合意义证明的话如图:

    23333

    233

    考虑第一个式子就相当于 ((0,0)) 到左边这一排黑点的方案数,那么考虑到这个红点的每一种方案,因为每一条路径穿过第一个黑点以后的方案数唯一,第一个式子正确性显然。

    第二个式子就相当于每一排的和,由第一个式子转化后就相当于要求右边这一排红点的方案数,先补上最下面一个红点,然后方案数就是到达黄点的方案数,最后再减去去掉经过最后一个红点的方案数 (1) 就是第二个式子

    实际上写成组合数的性质利用一些经典恒等式也可以证明,但这里用组合意义更有趣一点。

    code

    /*program by mangoyang*/
    #include <bits/stdc++.h>
    #define inf (0x7f7f7f7f)
    #define Max(a, b) ((a) > (b) ? (a) : (b))
    #define Min(a, b) ((a) < (b) ? (a) : (b))
    typedef long long ll;
    using namespace std;
    template <class T>
    inline void read(T &x){
    	int ch = 0, f = 0; x = 0;
    	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    	for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    	if(f) x = -x;
    }
    const int N = 2000005, mod = 1e9 + 7;
    int js[N], inv[N], X[7], Y[7], ans;
    inline void up(int &x, int y){ 
    	x = x + y >= mod ? x + y - mod : x + y; 
    }
    inline int Pow(int a, int b){
    	int ans = 1;
    	for(; b; b >>= 1, a = 1ll * a * a % mod)
    		if(b & 1) ans = 1ll * ans * a % mod;
    	return ans;
    }
    inline int C(int x, int y){
    	return 1ll * js[x] * inv[y] % mod * inv[x-y] % mod;
    }
    inline int GAO(int X1, int Y1, int X2, int Y2){
    	int res = 0;
    	up(res, C(X2 + Y2 + 2, Y2 + 1));
    	up(res, C(X1 + Y1, Y1));
    	up(res, mod - C(X2 + Y1 + 1, X2 + 1));
    	up(res, mod - C(Y2 + X1 + 1, Y2 + 1));
    	return res;
    }
    
    inline int gao1(int x, int y){
    	return 1ll * GAO(x - X[2], y - Y[2] - 1, x - X[1], y - Y[1] - 1)
    		* GAO(X[5] - x, Y[5] - y, X[6] - x, Y[6] - y) % mod;
    }
    inline int gao2(int x, int y){
    	return 1ll * GAO(x - X[2], y - Y[2], x - X[1], y - Y[1])
    		* GAO(X[5] - x, Y[5] - y - 1, X[6] - x, Y[6] - y - 1) % mod;
    }
    inline int gao3(int x, int y){
    	return 1ll * GAO(x - X[2] - 1, y - Y[2], x - X[1] - 1, y - Y[1])
    		* GAO(X[5] - x, Y[5] - y, X[6] - x, Y[6] - y) % mod;
    }
    inline int gao4(int x, int y){
    	return 1ll * GAO(x - X[2], y - Y[2], x - X[1], y - Y[1])
    		* GAO(X[5] - x - 1, Y[5] - y, X[6] - x - 1, Y[6] - y) % mod;
    }
    int main(){
    	js[0] = inv[0] = 1;
    	for(int i = 1; i < N; i++){
    		js[i] = 1ll * js[i-1] * i % mod;
    		inv[i] = Pow(js[i], mod - 2);
    	}
    	for(int i = 1; i <= 6; i++) read(X[i]);
    	for(int i = 1; i <= 6; i++) read(Y[i]);
    	for(int i = X[3]; i <= X[4]; i++){
    		up(ans, 1ll * gao1(i, Y[3]) * (mod - i - Y[3]) % mod);
    		up(ans, 1ll * gao2(i, Y[4]) * (i + Y[4] + 1) % mod);
    	}
    	for(int i = Y[3]; i <= Y[4]; i++){
    		up(ans, 1ll * gao3(X[3], i) * (mod - X[3] - i) % mod);
    		up(ans, 1ll * gao4(X[4], i) * (X[4] + i + 1) % mod);
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    HBase利用observer(协处理器)创建二级索引
    hbase系列-Hbase热点问题、数据倾斜和rowkey的散列设计
    大数据项目实战之新闻话题的实时统计分析
    kafka&&sparkstreaming整合入门之Wordcount
    项目总结
    JAVA实现阿里云接口完成短信验证
    Java中的23种设计模式之——适配器Adapter模式(2)
    Java中的23种设计模式之——单例模式(1)
    ElasticSearch使用ElasticsearchTemplate整合spring
    ElasticSearch安装和基本使用(1)
  • 原文地址:https://www.cnblogs.com/mangoyang/p/11766355.html
Copyright © 2011-2022 走看看