链接:http://hihocoder.com/problemset/problem/1699

快毕业了的菜菜,做了个比赛,遇到四维偏序,调成了傻逼,所以记录下,看了下以前的傻逼代码,发现自己的cdq居然用sort

怪不得总是被卡常,然后就是套路cdq+cdq,这类题的坑点就是有相同的矩形

贴代码:

 #include <stdio.h>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL N = 1e5 + ;
const LL mod = 1e9 + ; struct Point {
int x1, y1, x2, y2, partition, id;
bool operator < (const Point &p) const {
if(x1 != p.x1) return x1 < p.x1;
if(y1 != p.y1) return y1 < p.y1;
if(x2 != p.x2) return x2 > p.x2;
if(y2 != p.y2) return y2 > p.y2;
return id < p.id;
}
}p[N], o[N], tmp[N]; int n, bit[N], lim, ret[N]; void add(int x, int ad) {
for(; x <= lim; x += x & -x) bit[x] += ad;
} int ask(int x) {
int sum = ;
for(; x > ; x -= x & -x) sum += bit[x];
return sum;
} void cdq(int l, int r) {
if(l == r) return;
int mid = l + r >> ;
cdq(l, mid); cdq(mid + , r);
int i = l, j = mid + , cnt = l;
while(i <= mid || j <= r) {
if(i > mid) {
if(o[j].partition) ret[o[j].id] += ask(lim) - ask(o[j].y2 - );
tmp[cnt ++] = o[j ++];
} else if(j > r) {
if(!o[i].partition) add(o[i].y2, );
tmp[cnt ++] = o[i ++];
} else if(o[i].x2 >= o[j].x2) {
if(!o[i].partition) add(o[i].y2, );
tmp[cnt ++] = o[i ++];
} else {
if(o[j].partition) ret[o[j].id] += ask(lim) - ask(o[j].y2 - );
tmp[cnt ++] = o[j ++];
}
}
for(i = l; i <= mid; ++ i) if(!o[i].partition) add(o[i].y2, -);
for(i = l; i <= r; ++ i) o[i] = tmp[i];
} bool cmp(const Point &a, const Point &b) {
if(a.y1 != b.y1) return a.y1 < b.y1;
if(a.x2 != b.x2) return a.x2 > b.x2;
if(a.y2 != b.y2) return a.y2 > b.y2;
return a.id < b.id;
} void solve(int l, int r) {
if(l == r) return;
int mid = l + r >> ;
solve(l, mid); solve(mid + , r);
int i = l, j = mid + , cnt = l - ;
while(i <= mid || j <= r) {
if(i > mid) o[++ cnt] = p[j ++], o[cnt].partition = ;
else if(j > r) o[++ cnt] = p[i ++], o[cnt].partition = ;
else if(cmp(p[i], p[j])) o[++ cnt] = p[i ++], o[cnt].partition = ;
else o[++ cnt] = p[j ++], o[cnt].partition = ;
}
for(i = l; i <= r; ++ i) {
p[i] = o[i];
}
cdq(l, r);
}
int main() {
scanf("%d", &n);
for(int i = ; i <= n; ++ i) {
scanf("%d%d%d%d", &p[i].x1, &p[i].y1, &p[i].x2, &p[i].y2);
bit[++ lim] = p[i].y2;
p[i].id = i;
}
sort(bit + , bit + + lim);
lim = unique(bit + , bit + + lim) - bit - ;
for(int i = ; i <= n; ++ i) {
p[i].y2 = lower_bound(bit + , bit + + lim, p[i].y2) - bit;
}
for(int i = ; i <= lim; ++ i) bit[i] = ;
sort(p + , p + + n);
solve(, n);
sort(p + , p + + n);
for(int i = n - ; i > ; -- i) {
if(p[i].x1 == p[i + ].x1 && p[i].y1 == p[i + ].y1)
if(p[i].x2 == p[i + ].x2 && p[i].y2 == p[i + ].y2)
ret[p[i].id] = ret[p[i+].id];
}
for(int i = ; i <= n; ++ i) printf("%d\n", ret[i]);
return ;
}

hihocoder1699的更多相关文章

随机推荐

  1. [Python3网络爬虫开发实战] 1.8.4-Scrapy-Redis的安装

    Scrapy-Redis是Scrapy的分布式扩展模块,有了它,我们就可以方便地实现Scrapy分布式爬虫的搭建.本节中,我们将介绍Scrapy-Redis的安装方式. 相关链接 GitHub:htt ...

  2. 4.model 字段

    一.字段名 字段名 类型 参数 AutoField(Field) - int自增列, 必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自 ...

  3. PHP:验证手机号码合法性

    文章来源:http://www.cnblogs.com/hello-tl/p/7592333.html /** * [verifyPhone description] 效验手机号码合法性 * @par ...

  4. socket scoketserver

    import socket sk = socket.socket() # 创建了一个socket对象 # sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSE ...

  5. Texture 纹理贴图

    基础贴图Shader:只有纹理 1. 在属性中声明纹理贴图: _MainTex ("Texture", 2D) = "white" {} 2. 在Pass中声明 ...

  6. python之抽象 2014-4-6

    #抽象 8.40am-1.懒惰即美德2.抽象和结构3.创建函数 内建的callable 函数可以判定函数是否可以调用 >>> import math >>> x=1 ...

  7. JavaEE JDBC ResultSet内外移动

    ResultSet内外移动 @author ixenos 内外移动指位置光标的移动 内移动就是一个ResultSet得到后的那个光标! 外移动就是多个ResultSet的迭代 内移动 一般的数据库都不 ...

  8. 从一个简单的组件化封装写优化DOM操作

    /* *缺点 * 1. 还需要我们自己手工维护dom状态,以数据的思想去思考 *2. 数据改变后,还需要我们自己手动改变dom *3. * */ class LikeButton{ construct ...

  9. python基础之-字符串

    字符模块:strstr.strip():去掉字符串前后空格str.lstrip():去掉字符串左侧空格str.rstrip():去掉字符串右侧空格str.encode():将字符串编码为二进制str. ...

  10. Spring Cloud体系实现标签路由

    如果你正在使用Spring Cloud体系,在实际使用过程中正遇到以下问题,可以阅读本文章的内容作为后续你解决这些问题的参考,文章内容不保证无错,请务必仔细思考之后再进行实践. 问题: 1,本地连上开 ...