zoukankan      html  css  js  c++  java
  • LG3120 [USACO15FEB]Cow Hopscotch G CDQ分治维护DP顺序

    题目描述

    传送门

    题解

    容易得到转移方程 (dp(i,j)=sumlimits_{x=1}^{i-1}{sumlimits_{y=1}^{j-1}{dp(x,y)|a_{i,j} eq a_{x,y}}})

    边界条件为 (dp(1,1) = 1)

    然后呢,人傻了,这东西转移条件非常苛刻,都是严格小于。

    人傻数据结构来凑,写个线段树套线段树吧

    人又傻了,不会树套树啊。

    于是可以 cdq 分治维护 dp 顺序

    看这两个限制条件

    (egin{cases} x<i\ y<j end{cases})

    是一个二维偏序问题,可以强上 cdq 压掉一维。

    然后就傻逼题了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    template < typename Tp >
    inline void read(Tp &x) {
    	x = 0; int fh = 1; char ch = 1;
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') fh = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
    	x *= fh;
    }
    
    template < typename Tp >
    inline void biread(Tp &x) {
    	x = 0; int fh = 1; char ch = 1;
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') fh = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') x = x * 2 + ch - '0', ch = getchar();
    	x *= fh;
    }
    
    const int mod = 1000000007;
    
    int n, m, k;
    int s[750 * 750 + 7];
    int dp[757][757], a[757][757];
    
    void cdq(int l, int r) {
    	if(l == r) return ;
    	int mid = (l + r) >> 1;
    	cdq(l, mid);
    	int total = 0;
    	for(int i = 1; i <= m; i++) {
    		for(int j = mid + 1; j <= r; j++) {
    			dp[i][j] = ((dp[i][j] + total - s[a[i][j]]) % mod + mod) % mod;
    		}
    		for(int j = l; j <= mid; j++) {
    //			dp[i][j] = (dp[i][j] + total - s[a[i][j]]) % mod;
    			s[a[i][j]] = (s[a[i][j]] + dp[i][j]) % mod;
    			total = (total + dp[i][j]) % mod;
    		}
    	}
    	for(int i = 1; i <= m; i++) {
    		for(int j = l; j <= mid; j++) s[a[i][j]] = ((s[a[i][j]] - dp[i][j]) % mod + mod) % mod;
    	}
    	cdq(mid + 1, r);
    }
    
    inline void Init(void) {
    	read(n); read(m); read(k);
    	for(int i = 1; i <= n; i++) {
    		for(int j = 1; j <= m; j++) {
    			read(a[i][j]);
    		}
    	}
    }
    
    inline void Work(void) {
    	dp[1][1] = 1;
    	cdq(1, n);
    	printf("%d
    ", dp[n][m]);
    }
    
    signed main(void) {
    	Init();
    	Work();
    	return 0;
    }
    
  • 相关阅读:
    团队项目冲刺第五天
    团队项目冲刺第四天
    团队项目冲刺第三天
    团队项目冲刺第二天
    团队项目冲刺第一天
    团队任务命题
    java报错the superclass was not found 解决方案
    Buildings 分类: ACM 多校 2015-07-23 22:09
    1009 数字1的数量 分类: 51nod 2015-07-20 21:44 3人阅读 评
    1284 2 3 5 7的倍数 分类: 51nod 2015-07-18 22:06 6人阅读
  • 原文地址:https://www.cnblogs.com/liubainian/p/13857988.html
Copyright © 2011-2022 走看看