首页 > 其他分享 >cdq分治个人理解

cdq分治个人理解

时间:2024-02-27 09:35:30浏览次数:21  
标签:偏序 sort int 分治 mid 100005 理解 cdq

\([l,mid]\),跨越\(mid\),\([mid+1,r]\)
此时要考虑区间之间的影响。像拦截导弹和三维偏序就是不一样。因为不同区间的影响不一样。然后看代码

动态二维偏序,三维偏序,1D/1D 动态规划

#include<bits/stdc++.h>
using namespace std;
struct node{
	int a,b,c,sum,ans;
}b[100005],a[100005];
int n,m,k,cnt[100005],ans[100005],d[200005];//f{i}为多少 
int lowbit(int x){
	return x&(-x);
}
void update(int x,int ad){
	while(x<=k){
		d[x]+=ad;
		x+=lowbit(x);
	}
}
int getsum(int x){
	int ans=0;
	while(x){
		ans+=d[x];
		x-=lowbit(x);
	}
	return ans;
}
bool cmp1(node x,node y){//要加等号,不然会乱掉,不同数贡献会重
	if(x.a==y.a){
		if(x.b==y.b) return x.c<y.c;
		return x.b<y.b;
	}
	return x.a<y.a; 
}
bool cmp2(node x,node y){
	if(x.b==y.b) return x.c<y.c;
	return x.b<y.b;
}
void cdq(int l,int r){
	if(l==r) return;
	int mid=(l+r)>>1;
	cdq(l,mid);//运算顺序的问题
	cdq(mid+1,r);
	sort(a+l,a+mid+1,cmp2);
	sort(a+mid+1,a+r+1,cmp2);
	int i=l,j;
	for(j=mid+1;j<=r;j++){//如果a[i]>a[j],那么是j在循环,i对它贡献
		while(a[j].b>=a[i].b&&i<=mid)//b[i]之间大小关系影响这个 update(a[i].c,a[i].sum),i++;
		a[j].ans+=getsum(a[j].c);
	}//c[i]之间关系影响这个
	for(j=l;j<i;j++) update(a[j].c,-a[j].sum);
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>b[i].a>>b[i].b>>b[i].c;
	}
	sort(b+1,b+n+1,cmp1);//都是从小到大
	for(int i=1;i<=n;i++){//一定要去重,不然不同数贡献会重
		if(b[i].a==b[i-1].a&&b[i].b==b[i-1].b&&b[i].c==b[i-1].c){
			a[m].sum++;
		}else{
			m++;
			a[m]=b[i];
			a[m].sum=1;
		}
	}
	cdq(1,m);
	for(int i=1;i<=m;i++){
		ans[a[i].ans+a[i].sum-1]+=a[i].sum;
	}
	for(int i=0;i<n;i++){
		cout<<ans[i]<<"\n";
	}
	
	return 0;
}

标签:偏序,sort,int,分治,mid,100005,理解,cdq
From: https://www.cnblogs.com/wuhupai/p/18036161

相关文章

  • sol CF587F AC 自动机 根号分治
    注意下文中fail树和trie树的不同。考虑给询问离线,然后差分成\([1,r]-[1,l-1]\)的前缀询问来做。先对于\(s_{1\dotsn}\)建立AC自动机。从左到右扫描询问,当扫描到\(i\)时就对fail树上的子树\(i\)全体\(+1\),使用树状数组维护即可。答案即为\(s_k\)在trie树......
  • 根号分治与莫队算法
    1.根号分治与分块在预处理与询问的复杂度之间寻找平衡的一个算法,通常以根号为分界线。属于智慧的暴力。1.1.根号平衡使用数学不等式对于阈值取一个值,使得复杂度最优。如果有阈值\(B\),若问题有一部分暴力可以\(O(B)\)解决,另一部分可以\(O(\frac{n}{B})\)解决。那么根据基......
  • 自己卷自己的分治 NTT
    考虑如下卷积:\[f_i=\sum\limits_{j=1}^{i-1}f_jf_{i-j}\]仍然可以cdq分治计算。考虑当前在\([l,r]\),希望计算\([l,mid]\)贡献到\([mid+1,r]\)。若\(r-l<l\)那么\([1,r-l]\)都被算出,直接用\([1,r-l]\)和\([l,mid]\)卷两遍即可;否则\(l......
  • 猫树分治
    就是说,对于分治区间\([l,r]\),记\(mid=\lfloor\dfrac{l+r}{2}\rfloor\),对于\([l,mid]\)和\([mid+1,r]\)内的询问继续递归,把跨越两边的询问用左右的信息合并处理。P6240好吃的题目物品\(i\)有体积\(w_i\)和价值\(c_i\),多次询问,对\([l,r]\)做01背包,问体积\(\let......
  • 能碳双控| AIRIOT智慧能碳管理解决方案
     在当前全球气候变化和可持续发展的背景下,建设能碳管理平台成为组织迎接挑战、提升可持续性的重要一环,有助于组织实现可持续发展目标,提高社会责任形象,同时适应未来碳排放管理的挑战。能碳管理是一个涉及跟踪、报告和减少组织碳排放的复杂过程,往往存在如下痛点: 数据收集的准......
  • 个人在学习过程中对多线程和异步的理解
    私人对于异步与多线程的理解前言​ 异步与多线程都是并发问题的一种解决方式,但是异步是程序员层面,线程是操作系统层面的。​ 其次,异步与线程解决并发问题的实现方式和目的是不同的。下面举一个不太贴切的例子。如果把线程当作一条单行道,那么多线程就是通过扩展多条道路从而实现......
  • C# 理解Thread.Sleep()方法
    C#理解Thread.Sleep()方法转载:https://www.cnblogs.com/nzbbody/archive/2012/03/06/2381359.html我们可能经常会用到Thread.Sleep函数来使线程挂起一段时间。那么你有没有正确的理解这个函数的用法呢?思考下面这两个问题:1、假设现在是2008-4-712:00:00.000,如果我调用一下......
  • 猫树分治
    就是说,对于分治区间\([l,r]\),记\(mid=\lfloor\dfrac{l+r}{2}\rfloor\),对于\([l,mid]\)和\([mid+1,r]\)内的询问继续递归,把跨越两边的询问用左右的信息合并处理。P6240好吃的题目物品\(i\)有体积\(w_i\)和价值\(c_i\),多次询问,对\([l,r]\)做01背包,问体积\(\let......
  • IOC简单理解
    IOCrefreshBeanFactory()0、实例化IOC容器(就是一个Map<String,BeanDefinition>)1、资源加载器加载解析配置文件资源加载器接口ResourceLoader资源的抽象和访问接口ResourceFileSystemResource,文件系统资源的实现类ClassPathResource,classpath下资源的实现类UrlReso......
  • 通俗理解微服务
    微服务是什么?-阮一峰的网络日志(ruanyifeng.com)......