CDQ分治或树套树可以切掉
CDQ框架:

  • 先分
  • 计算左边对右边的贡献
  • 再和

所以这个题可以一维排序,二维CDQ,三维树状数组统计
CDQ代码

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <algorithm>
# include <string.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x * z;
} const int MAXN(100010), MAXK(200010);
int n, k, t[MAXK], m;
struct Point{
int a, b, c, cnt, id, ans;
IL bool operator ==(RG Point B) const{ return a == B.a && b == B.b && c == B.c; }
} p[MAXN], q[MAXN]; IL bool Cmp1(RG Point x, RG Point y){ return x.a < y.a || (x.a == y.a && (x.b < y.b || (x.b == y.b && x.c < y.c))); } IL bool Cmp2(RG Point x, RG Point y){ return x.b < y.b || (x.b == y.b && (x.c < y.c || (x.c == y.c && x.a < y.a))); } IL void Add(RG int x, RG int d){ for(; x <= k; x += x & -x) t[x] += d; } IL int Query(RG int x){ RG int cnt = 0; for(; x; x -= x & -x) cnt += t[x]; return cnt; } IL void CDQ(RG int l, RG int r){
if(l == r) return;
RG int mid = (l + r) >> 1; CDQ(l, mid); CDQ(mid + 1, r);
sort(p + l, p + r + 1, Cmp2);//可以归并排序
for(RG int i = l; i <= r; i++)
if(p[i].id <= mid) Add(p[i].c, p[i].cnt);
else p[i].ans += Query(p[i].c);
for(RG int i = l; i <= r; i++)
if(p[i].id <= mid) Add(p[i].c, -p[i].cnt);
} int main(RG int argc, RG char* argv[]){
n = Read(); k = Read();
for(RG int i = 1; i <= n; i++) q[i] = (Point){Read(), Read(), Read()};
sort(q + 1, q + n + 1, Cmp1);
for(RG int i = 1; i <= n; i++)
if(q[i] == p[m]) p[m].cnt++;
else p[++m] = q[i], p[m].cnt = 1, p[m].id = m;
CDQ(1, m);
sort(p + 1, p + m + 1, Cmp1);
for(RG int i = 1; i <= m; i++) t[p[i].ans + p[i].cnt - 1] += p[i].cnt;
for(RG int i = 0; i < n; i++) printf("%d\n", t[i]);
return 0;
}

附上树套树

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <algorithm>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL ll Read(){
RG char c = getchar(); RG ll x = 0, z = 1;
for(; c > '9' || c < '0'; c = getchar()) z = c == '-' ? -1 : 1;;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + c - '0';
return x * z;
} const int MAXN(100010);
int n, k, ans[MAXN], NOW;
struct YYB{
int a, b, c;
IL bool operator <(RG YYB B) const{
if(a != B.a) return a < B.a;
if(b != B.b) return b < B.b;
return c < B.c;
}
IL bool operator ==(RG YYB B) const{
return a == B.a && b == B.b && c == B.c;
}
} yyb[MAXN];
struct SBT{
SBT *ch[2], *fa;
int size, val, cnt;
IL SBT(RG SBT *f, RG int v, RG int d){ cnt = size = d; val = v; fa = f; }
} *rt[MAXN << 1]; IL int Son(RG SBT *x){ return x -> fa -> ch[1] == x; } IL int Size(RG SBT *x){ return x == NULL ? 0 : x -> size; } IL void Updata(RG SBT *x){ x -> size = Size(x -> ch[0]) + Size(x -> ch[1]) + x -> cnt; } IL void Rot(RG SBT *x){
RG int c = !Son(x); RG SBT *y = x -> fa;
y -> ch[!c] = x -> ch[c];
if(x -> ch[c] != NULL) x -> ch[c] -> fa = y;
x -> fa = y -> fa;
if(y -> fa != NULL) y -> fa -> ch[Son(y)] = x;
x -> ch[c] = y; y -> fa = x;
Updata(y);
} IL void Splay(RG SBT *x, RG SBT *f){
while(x -> fa != f){
RG SBT *y = x -> fa;
if(y -> fa != f)
Son(x) ^ Son(y) ? Rot(x) : Rot(y);
Rot(x);
}
Updata(x); rt[NOW] = x;
} IL void Insert(RG SBT *x, RG int v, RG int d){
if(rt[NOW] == NULL){ rt[NOW] = new SBT(NULL, v, d); return; }
while(2333){
RG int id = v > x -> val;
if(v == x -> val){ x -> size += d; x -> cnt += d; break; }
if(x -> ch[id] == NULL){
x -> ch[id] = new SBT(x, v, d);
x = x -> ch[id];
break;
}
x = x -> ch[id];
}
Splay(x, NULL);
} IL int Calc(RG SBT *x, RG int v){
RG int cnt = 0;
while(x != NULL){
if(v >= x -> val) cnt += Size(x -> ch[0]) + x -> cnt;
if(v == x -> val) break;
x = x -> ch[v > x -> val];
}
return cnt;
} IL void Modify(RG int id, RG int d){
for(NOW = yyb[id].b; NOW <= k; NOW += NOW & -NOW) Insert(rt[NOW], yyb[id].c, d);
} IL int Query(RG int id){
RG int cnt = 0;
for(RG int i = yyb[id].b; i; i -= i & -i) cnt += Calc(rt[i], yyb[id].c);
return cnt;
} int main(){
n = Read(); k = Read();
for(RG int i = 1; i <= n; i++)
yyb[i] = (YYB){Read(), Read(), Read()};
sort(yyb + 1, yyb + n + 1);
for(RG int i = 1, sum = 0; i <= n; i++){
sum++;
if(yyb[i] == yyb[i + 1]) continue;
ans[Query(i) + sum - 1] += sum;
Modify(i, sum);
sum = 0;
}
for(RG int i = 0; i < n; i++) printf("%d\n", ans[i]);
return 0;
}

最新文章

  1. Linux Shell基础知识
  2. expect结合ssh遍历线上机器
  3. JAVA6开发WebService (二)——JAX-WS例子
  4. 基础学习day12--多线程一线程之间的通信和常用方法
  5. placeholder在不同浏览器下的表现及兼容方法
  6. Java中的JDBC基础
  7. MySQL在ROW模式下通过binlog提取SQL语句
  8. C# Generic(转载)
  9. 并查集 poj1611&amp;poj2492
  10. #Leet Code# Root to leaf
  11. debian系统下安装ssh服务
  12. ios url网址相关问题解说
  13. &quot;Cache-control”常见的取值private、no-cache、max-age、must-revalidate及其用意
  14. CSS3 border-radius 圆角
  15. Linq to SQL -- Group By、Having和Exists、In、Any、All、Contains
  16. 关于div文字点击编辑的插件
  17. 修改Anaconda中的Jupyter Notebook默认工作路径
  18. Myeclipse项目中Source、Projects、Libraries、Order and export含义
  19. 基于CAS操作的非阻塞算法
  20. “Spring.Context.Support.ContextRegistry”的类型初始值设定项引发异常。-解决方法

热门文章

  1. linux服务器ssh、公匙和密钥实战详解
  2. ajaxfileupload批量上传文件+图片尺寸限制
  3. 插入排序实现&amp;&amp;选择排序实现
  4. .NET中的按需加载/延迟加载 Lazy&lt;T&gt;
  5. Centos下Sphinx中文分词编译安装测试---CoreSeek
  6. LOJ6002 - 「网络流 24 题」最小路径覆盖
  7. 吾八哥学Selenium(四):操作下拉框select标签的方法
  8. Unix代码段和数据段
  9. mysql常用脚本及命令记录
  10. 自己编写的仿京东移动端的省市联动选择JQuery插件