zoukankan      html  css  js  c++  java
  • 【CS Round #48 (Div. 2 only)】Dominant Free Sets

    【链接】h在这里写链接


    【题意】


    让你在n个点组成的集合里面选取不为空的集合s.
    使得这里面的点没有出现某个点a和b,ax>=bx且ay>=by;
    问你s的个数。

    【题解】


    我们把这些点按照(x,y)升序排(x优先,y次之).
    然后按顺序处理这些点。
    会发现.
    我们在处理(x,y)点的时候.
    只有它的左上方那些点是可以和他在一起的。
    (也即xi<x 且 yi > y)
    随便取左上方的矩形区域里面的一个点。都能组成一个集合。
    但是随便取的那个点,可能也可以和它的左上方的更小的矩形区域里的某个点组合。
    会发现这是一个DP的问题。
    只要维护sum((x,y)的左上角矩形区域内的dp(x,y) )就可以了。
    因为随便加上哪一个点的dp(xi,yi),就表示一定选(x,y)和(xi,yi)然后问题就能转化成以(xi,yi)作为(x,y)的一个问题了。
    (隐藏含义:xi+1..x之间的所有点都不选。)
    这个问题显然是重叠的。(之前已经解决过了。);
    写个树状数组就能搞定。
    把(1,1)..(x,y)这个矩形区域的减掉。就是左上角的了。
    (选完(x,y)之后,dp(x,y)=左上角的dp(x,y)之和 + 1)
    (因为不选(x,y)的左上角里的任意一个点也是可以的,只选(x,y),供后面的点继续做DP);
    但是答案只递增(x,y)左上角的dp(x,y)之和

    【错的次数】


    0

    【反思】


    在这了写反思

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    
    const int N = 1e5;
    const long long MOD = 1e9 + 7;
    
    
    struct BI {
    	long long a[N + 10];
    
    
    	int lowbit(int x) {
    		return x&(-x);
    	}
    
    
    	void add(int x, long long y) {
    		while (x <= N) {
    			a[x] = ((a[x] + y) % MOD + MOD) % MOD;
    			x += lowbit(x);
    		}
    	}
    
    
    	long long sum(int x) {
    		long long now = 0;
    		while (x > 0) {
    			now = ((now + a[x]) % MOD + MOD) % MOD;
    			x -= lowbit(x);
    		}
    		return now;
    	}
    
    
    	long long get_sum(int l, int r) {
    		return sum(r) - sum(l - 1);
    	}
    
    
    }b;
    
    
    vector <pair <int, int> > v;
    int n;
    long long sum = 0, ans = 0;
    
    
    int main() {
    	//freopen("F:\\rush.txt", "r", stdin);
    	ios::sync_with_stdio(0), cin.tie(0);
    	cin >> n;
    	for (int i = 1, x, y; i <= n; i++) {
    		cin >> x >> y;
    		v.push_back(make_pair(x, y));
    	}
    	sort(v.begin(), v.end());
    	b.add(v[0].second, 1);
    	int j = 1;
    	sum = 1;
    	while (j <= (int)v.size() - 1 && v[j].first == v[0].first) {
    		b.add(v[j].second, 1);
    		sum += 1;
    		j++;
    	}
    	ans = n;
    	for (int i = j; i <= n - 1; i++) {
    		long long temp = b.get_sum(1, v[i].second);
    		long long temp1 = ((sum - temp) % MOD + MOD) % MOD;
    		b.add(v[i].second, (temp1 + 1) % MOD);
    		ans = (ans + temp1) % MOD;
    		sum = (sum + temp1 + 1) % MOD;
    	}
    	cout << ans << endl;
    	return 0;
    }


  • 相关阅读:
    数据库设计三大范式
    MySQL笔试题搜罗
    [转载]MySql事物处理
    网页错误代码大全
    【转载】linux环境下大数据网站搬家
    Linux常用命令
    MongoDB概述
    Linux系统下通过命令行对mysql数据进行备份和还原
    wamp提示:与服务器的连接断开,请检查网络状况与服务器的运行状态的解决方法
    HDU 4578 线段树各种区间操作
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626019.html
Copyright © 2011-2022 走看看