首页 > 其他分享 >【洛谷P3810】 【模板】三维偏序(陌上花开)

【洛谷P3810】 【模板】三维偏序(陌上花开)

时间:2022-11-18 17:14:05浏览次数:48  
标签:偏序 洛谷 int void mid P3810 solve const define

CDQ是一中思想,用来求点对数列。
定义\(solve(l,r)\)用来求\([l,r]\)区间的数对,
那么先递归处理\(solve(l,mid)\),
然后考虑前半段对后半段的影响,
然后再递归处理后半段\(solve(mid+1,r)\)

对于这道题,具体就是,先按\(a\)排序,然后\(solve(l,r)\)先递归处理两边,然后考虑怎么统计\(i\)在前半段,\(j\)在后半段的满足\(b_i\leq b_j\)且\(c_i\leq c_j\)的个数。
可以先对这两端按\(b\)排序,然后双指针一个个把左边的\(c\)插到树状数组里,枚举右边的直接统计。

#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define pb push_back
#define rep(i, m, n) for(int i = (m); i <= (n); ++i)
#define dop(i, m, n) for(int i = (m); i >= (n); --i)
#define all(x) x.begin(), x.end()
#define Open(s) freopen(s,"r",stdin);
#define Write(s) freopen(s,"w",stdout);
using namespace std;
typedef long long ll;
template <class T> void chkmin(T &a, T b){ if(a > b) a = b; }
template <class T> void chkmax(T &a, T b){ if(a < b) a = b; }
template <class T> T aabs(T a){ return a > 0 ? a : -a; }
const int N = 200010;
struct node{
	int num, a, b, c, ans;
	void input(){
		scanf("%d%d%d", &a, &b, &c);
	}
}q[N], p[N];
int n, k;
int cmp(const node& a, const node& b){
	return a.b != b.b ? a.b < b.b : a.c < b.c;
};
int s[N], cnt[N];
void add(int x, int y){
	while(x <= k){
		s[x] += y;
		x += lowbit(x);
	}
}
int ask(int x){
	int ans = 0;
	while(x){
		ans += s[x];
		x -= lowbit(x);
	}
	return ans;
}
void solve(int l, int r){
	if(l == r) return;
	int mid = l + r >> 1;
	solve(l, mid); solve(mid + 1, r);
	sort(p+l, p+mid+1, cmp);
	sort(p+mid+1, p+r+1, cmp);
	int cur = l - 1;
	rep(i, mid+1, r){
		while(cur < mid && p[cur+1].b <= p[i].b){
			++cur; add(p[cur].c, p[cur].num);
		}
		p[i].ans += ask(p[i].c);
	}
	rep(i, l, cur) add(p[i].c, -p[i].num);
}
int main(){
	scanf("%d%d", &n, &k); int m = n;
	rep(i, 1, n) q[i].input();
	sort(q+1, q+n+1, [](node& a, node& b){
		return a.a != b.a ? a.a < b.a : (a.b != b.b ? a.b < b.b : a.c < b.c);
	});
	n = 0;
	rep(i, 1, m){
		if(q[i].a != q[i-1].a || q[i].b != q[i-1].b || q[i].c != q[i-1].c){
			p[++n] = q[i]; p[n].num = 1;
		}
		else p[n].num++;
	}
	solve(1, n);
	rep(i, 1, n) cnt[p[i].ans + p[i].num - 1] += p[i].num;
	rep(i, 0, m-1) printf("%d\n", cnt[i]);
	return 0;
}

标签:偏序,洛谷,int,void,mid,P3810,solve,const,define
From: https://www.cnblogs.com/Qihoo360/p/16903858.html

相关文章

  • 洛谷-3758
    洛谷-3758思路一定要看数据范围!Code#include<bits/stdc++.h>usingnamespacestd;#define_u_u_ios::sync_with_stdio(false),cin.tie(nullptr)#definecfint_......
  • 洛谷刷题_P1255 数楼梯
    题目P1255数楼梯题目链接https://www.luogu.com.cn/problem/P1255知识点斐波那契数列斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13、21、34、……,在数学上,......
  • 邮递员送信(洛谷1629)
    ​​传送门​​​第一反应是Floyd,但是看看数据规模,会tle那就考虑n次单源最短路,但是即使是SPFA,也会t那肯定就另有玄机。我们每次出去送货后都要直接返回邮局,所以我们需要......
  • 洛谷-1714
    洛谷-1714思路求连续子段,显然需要前缀和处理一下,问题就变成了求出\(i,j\)使得\[\max\{s[i]-s[j]\},i-j>m\]于是利用双端队列从每个区间的max-min中找答案。但......
  • 记录一下某一个log的三维偏序
    求\(a_i<a_j,b_i<b_j,c_i<c_j\)的数对个数。先把三个二维偏序拆出来跑一遍。然后看贡献:三维偏序:一个算了三次。二维:一个算了一次。剩下的:没算。然后发现三维+二维=......
  • 【LGR-125】洛谷 11 月月赛 I & JROI-7 & JRKSJ-5
    P8846『JROI-7』PMK配匹串符字简要题意给出一正整数\(n(1\leqn\leq10^5)\),求出一个由小写英文字母组成的字符串\(S\),使得\(|S|=n\)且\(\sum_{i=1}^{n}{\opera......
  • 洛谷题单【入门2】分支结构-P1085 [NOIP2004 普及组] 不高兴的津津
    题目描述津津上初中了。妈妈认为津津应该更加用功学习,所以津津除了上学之外,还要参加妈妈为她报名的各科复习班。另外每周妈妈还会送她去学习朗诵、舞蹈和钢琴。但是津津......
  • 洛谷题单【入门1】顺序结构-P1001 A+B Problem
    题目描述输入两个整数 a,ba,b,输出它们的和(|a|,|b|\le{10}^9∣a∣,∣b∣≤109)。 输入格式两个以空格分开的整数。输出格式一个整数。输入输出样例输......
  • 洛谷题单【入门1】顺序结构-B2005 字符三角形
    题目描述给定一个字符,用它构造一个底边长 55 个字符,高 33 个字符的等腰字符三角形。输入格式输入只有一行,包含一个字符。输出格式该字符构成的等腰三角形,底......
  • 洛谷题单【入门1】顺序结构-P1000 超级玛丽游戏
    题目描述超级玛丽是一个非常经典的游戏。请你用字符画的形式输出超级玛丽中的一个场景。********************####........