• BZOJ 1818: [Cqoi2010]内部白点 (BIT + 扫描线)


    就是求多条线段的交点数,直接BIT+扫描线就行了. 注意不要算重最初存在的点.

    CODE

    #include<bits/stdc++.h>
    using namespace std;
    char cb[1<<15],*cs=cb,*ct=cb;
    #define getc() (cs==ct&&(ct=(cs=cb)+fread(cb,1,1<<15,stdin),cs==ct)?0:*cs++)
    template<class T>inline void read(T &res) {
    	char ch; int flg = 1; for(;!isdigit(ch=getc());)if(ch=='-')flg=-flg;
    	for(res=ch-'0';isdigit(ch=getc());res=res*10+ch-'0'); res*=flg;
    }
    const int MAXN = 100005;
    struct node { int x, y; }a[MAXN];
    struct Node { int x, y, v; inline bool operator <(const Node &o)const { return y < o.y; } }q[MAXN];
    inline bool cmpx(const node &a, const node &b) { return a.x == b.x ? a.y < b.y : a.x < b.x; }
    inline bool cmpy(const node &a, const node &b) { return a.y == b.y ? a.x < b.x : a.y < b.y; }
    int n, T[MAXN], b[MAXN], tot, N;
    inline void upd(int x, int val) { while(x <= N) T[x] += val, x += x&-x; }
    inline int qsum(int x) { int re = 0; while(x) re += T[x], x -= x&-x; return re; }
    int main() {
    	read(n);
    	for(int i = 1; i <= n; ++i)
    		read(a[i].x), read(a[i].y), b[++N] = a[i].x;
    	sort(b + 1, b + N + 1);
    	N = unique(b + 1, b + N + 1) - b - 1;
    	for(int i = 1; i <= n; ++i) //离散化x坐标
    		a[i].x = lower_bound(b + 1, b + N + 1, a[i].x) - b;
    	sort(a + 1, a + n + 1, cmpx);
    	for(int i = 1, j; i <= n; i = j) {
    		int L = a[i].y, R;
    		for(j = i; j <= n && a[j].x == a[i].x; ++j)
    			R = a[j].y;
    		if(R-L > 1) { //差分
    			++tot, q[tot].x = a[i].x, q[tot].y = L+1, q[tot].v = 1;
    			++tot, q[tot].x = a[i].x, q[tot].y = R, q[tot].v = -1;
    		}
    	}
    	sort(a + 1, a + n + 1, cmpy);
    	sort(q + 1, q + tot + 1);
    	int cur = 1, ans = n;
    	for(int i = 1, j; i <= n; i = j) {
    		while(cur <= tot && q[cur].y <= a[i].y)
    			upd(q[cur].x, q[cur].v), ++cur;
    			for(j = i+1; j <= n && a[j].y == a[i].y; ++j)
    				if(a[j-1].x+1 <= a[j].x-1)
    					ans += qsum(a[j].x-1) - qsum(a[j-1].x); //差分
    				//注意这里不能只用最靠左和最靠右的点形成的线段在BIT里查找
    				//因为这段里面可能有最初就存在的黑点
    	}
    	printf("%d
    ", ans);
    }
    
  • 相关阅读:
    Android 重写系统Crash处理类,保存Crash信息到SD卡 和 完美退出程序的方法
    LeetCode第二十四题-交换链表中节点值
    LeetCode第二十三题-合并n个有序链表
    LeetCode第二十二题-创建n对括号
    LeetCode第二十一题-对两个有序链表排序
    LeetCode第二十题-有效的括号
    LeetCode第十九题-链表节点的删除
    LeetCode第十八题-四数之和
    LeetCode第十七题-电话号码的字母组合
    LeetCode第十六题-找出数组中三数之和最接近目标值的答案
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039330.html
Copyright © 2020-2023  润新知