• Tokitsukaze and Strange Rectangle CodeForces


    大意: 给定$n$个平面点, 定义集合$S(l,r,a)$表示横坐标$[l,r]$纵坐标$[a,infty]$内的所有点. 求可以得到多少种不同的集合.

    从上往下枚举底层最右侧点, 树状数组统计贡献.

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    using namespace std;
    typedef long long ll;
    const int N = 1e6+10, INF = 0x3f3f3f3f;
    int n, c[N], vis[N], b[N];
    struct _ {
    	int x,y;
    	bool operator < (const _&rhs) const {
    		if (y!=rhs.y) return y>rhs.y;
    		return x<rhs.x;
    	}
    } a[N];
    int ID(int x) {
    	return lower_bound(b+1,b+1+*b,x)-b;
    }
    int qry(int x) {
    	int r = 0;
    	for (; x; x^=x&-x) r+=c[x];
    	return r;
    }
    int qry(int l, int r) {
    	return qry(ID(r))-qry(ID(l-1));
    }
    void add(int x) {
    	x = ID(x);
    	if (!vis[x]) {
    		vis[x] = 1;
    		for (; x<=*b; x+=x&-x) ++c[x];
    	}
    }
    int main() {
    	scanf("%d", &n);
    	REP(i,1,n) { 
    		scanf("%d%d",&a[i].x,&a[i].y);
    		b[++*b]=a[i].x;
    		b[++*b]=a[i].x-1;
    	}
    	b[++*b]=0,b[++*b]=INF;
    	sort(b+1,b+1+*b),*b=unique(b+1,b+1+*b)-b-1;
    	sort(a+1,a+1+n);
    	ll ans = 0;
    	REP(i,1,n) {
    		int j=i;
    		while (j<n&&a[j+1].y==a[i].y) ++j;
    		REP(k,i,j) { 
    			int L = qry(1,a[k].x-1);
    			int R = qry(a[k].x+1,k==j?INF:a[k+1].x-1);
    			ans += (ll)(L+1)*(R+1);
    			add(a[k].x);
    		}
    		i = j;
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    mysql 存储过程中的 prepare语句(存储过程中动态增减表字段)
    MYSQL创建分区时候报错
    mysql存储过程调试方法
    磁力块[分块]
    区间最优覆盖问题[差分]
    区间最优覆盖问题[差分]
    导弹防御[差分]
    导弹防御[差分]
    CF10D LCIS[动态规划]
    CF10D LCIS[动态规划]
  • 原文地址:https://www.cnblogs.com/uid001/p/11183907.html
Copyright © 2020-2023  润新知