思路

看到这种偏序类的题目,而且不要求强制在线,可以立刻想到cdq分治

注意这题有一个问题,就是询问的是小于等于而不是小于,如果相等的话两个元素会相互贡献,而cdq的特点是右区间不能对左边有影响,所以要先去重,再然后就是板子

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,maxn;
namespace BIT{
int bit[200100];
int lowbit(int x){
return x&(-x);
}
void add(int pos,int val){
while(pos<=maxn){
bit[pos]+=val;
pos+=lowbit(pos);
}
}
int query(int pos){
int ans=0;
while(pos){
ans+=bit[pos];
pos-=lowbit(pos);
}
return ans;
}
void clear(int pos){
while(pos<=maxn){
if(bit[pos])
bit[pos]=0;
else
break;
pos+=lowbit(pos);
}
}
}
struct Num{
int a,b,c,val;
bool operator == (const Num &bx) const{
if(a==bx.a&&b==bx.b&&c==bx.c)
return true;
return false;
}
bool operator < (const Num &bx) const{
if(a<bx.a)
return true;
else if(a==bx.a&&b<bx.b)
return true;
else if(a==bx.a&&b==bx.b&&c<bx.c)
return true;
else return false;
}
}a[100100],num[100100];
int ans[100100],d[100100];
int cntnum=0,qid,aid;
struct Query{
int posx,valy,val,aid;
}query[100100<<1];
Query tmp[100100<<1];
void cdq(int L,int R){
// printf("%d %d\n",L,R);
if(R<=L+1)
return;
int mid=(L+R)>>1;
cdq(L,mid);
cdq(mid,R);
int l=L,r=mid,tot=0;
while(l<mid&&r<R){
if(query[l].posx<=query[r].posx){
BIT::add(query[l].valy,query[l].val);
tmp[++tot]=query[l++];
}
else{
ans[query[r].aid]+=BIT::query(query[r].valy);
tmp[++tot]=query[r++];
}
}
while(l<mid)
tmp[++tot]=query[l++];
while(r<R){
ans[query[r].aid]+=BIT::query(query[r].valy);
tmp[++tot]=query[r++];
}
for(int i=1;i<=tot;i++){
BIT::clear(tmp[i].valy);
query[i+L-1]=tmp[i];
}
}
int main(){
scanf("%d %d",&n,&maxn);
for(int i=1;i<=n;i++)
scanf("%d %d %d",&a[i].a,&a[i].b,&a[i].c),a[i].val=1;
sort(a+1,a+n+1);
// printf("ok\n");
// for(int i=1;i<=n;i++)
// printf("%d %d %d\n",a[i].a,a[i].b,a[i].c);
num[++cntnum]=a[1];
for(int i=1;i<=n-1;i++){
if(a[i]==a[i+1])
num[cntnum].val++;
else
num[++cntnum]=a[i+1];
}
for(int i=1;i<=cntnum;i++){
query[++qid].posx=num[i].b;
query[qid].aid=++aid;
query[qid].valy=num[i].c;
query[qid].val=num[i].val;
}
// printf("ok\n");
cdq(1,qid+1);
for(int i=1;i<=qid;i++){
d[ans[query[i].aid]+query[i].val-1]+=query[i].val;
}
for(int i=0;i<=n-1;i++)
printf("%d\n",d[i]);
return 0;
}

最新文章

  1. 清北 Noip 2016 考前刷题冲刺济南班
  2. 表单验证神器——jquery.validate插件
  3. Linux多线程实例练习 - pthread_cancel()
  4. 【第三课】ANR和OOM——贪快和贪多的后果(上)
  5. PAT 1038 体验Python之美
  6. Cppcheck软件使用
  7. linux下各种文件格式的压缩以及解压缩命令
  8. 读取的XML节点中带有冒号怎么办?
  9. 转 html5离线储存,application cache,manifest使用体验
  10. HTML 字符集
  11. JSP标签JSTL的使用(1)--表达式操作
  12. Adb工具的简单使用
  13. linux服务器升级nginx
  14. 【java】抽象类和接口区别
  15. YAML配置:mapping values are not allowed here
  16. IIC通讯协议(非原创,转载他人,用于学习)
  17. Android动态添加Device Admin权限
  18. Day Eight
  19. 激活Window和office工具
  20. JDK1.8 重识HashMap

热门文章

  1. 【Redis学习之六】Redis数据类型:集合和有序集合
  2. 举例说明Unicode 和UTF-8之间的转换
  3. python selenium设置chrome的下载路径
  4. 使用Flask-CKEditor集成富文本编辑框
  5. flask 在模板中渲染表单
  6. linux下卸载mysql(rpm)
  7. C#获取驱动器盘符
  8. str int list tuple dict 一些实操
  9. Numpy 通用函数
  10. ORM for Net主流框架汇总