3.18

博客介绍了printf函数原型与功能,还提及离散化技巧,可降低时间复杂度,介绍了其实现步骤。此外,探讨了树状数组求逆序对、区间最大值等,强调线段树空间开辟问题,最后给出编程题目及解题思路,如创建平衡编程团队问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.cnblogs.com/noblex/p/9197896.html

相当于废话了

函数原型:int printf (char * format,args,···); 

功能:按format指向的格式字符串所规定的格式,将输出表列args的值输出到标准输出设备。

例题:

输入i=56479854987; 

输出最终结果就是56479854987112; 

因为56479854987是11个字符,11是两个字符;

https://www.cnblogs.com/xingyunblog/p/3657580.html

printf返回值了解一下

  题目链接   http://acm.hdu.edu.cn/showproblem.php?pid=1166

离散化是程序设计中一个常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中,只考虑需要用的值。离散化可以改进一个低效的算法,甚至实现根本不可能实现的算法。要掌握这个思想,必须从大量的题目中理解此方法的特点。例如,在建造线段树空间不够的情况下,可以考虑离散化。

思路是:先排序,再删除重复元素,最后就是索引元素离散化后对应的值。

假定待离散化的序列为a[n],b[n]是序列a[n]的一个副本,则对应以上三步为:

sort(sub_a,sub_a+n);

int size=unique(sub_a,sub_a+n)-sub_a;//size为离散化后元素个数

for(i=0;i<n;i++)

a[i]=lower_bound(sub_a,sub_a+size,a[i])-sub_a + 1;//k为b[i]经离散化后对应的值

对于第3步,若离散化后序列为0,1,2,...,size - 1则用lower_bound,从1,2,3,...,size则用upper_bound。其中lower_bound返回第1个不小于b[i]的值的指针,而upper_bound返回第1个大于b[i]的值的指针,当然在这个题中也可以用lower_bound然后再加1得到与upper_bound相同结果,两者都是针对以排好序列。使用STL离散化大大减少了代码量且结构相当清晰。

树状数组竟然可以求逆序对,之前倒是不清楚

https://blog.youkuaiyun.com/SSimpLe_Y/article/details/53744096

#include<bits/stdc++.h>
using namespace std;
struct node{
	int v,pos;
	
}nod[100010];int n;
int tree[100010];
void update(int sum){
	for(int i=sum;i<=n;i+=(i&(-i))){
		tree[i]+=1;
	}
	return;
}
int cmp(node a,node b){
	return a.v<b.v;
}
int getsum(int x){
	int sum=0;
	for(int i=x;i;i-=(i&(-i))){
		sum+=tree[i];
	}
	return sum;
}
int main(){

	cin>>n;int ans=0;
	for(int i=1;i<=n;i++){
		cin>>nod[i].v;
		nod[i].pos=i;
	}
	sort(nod+1,nod+n+1,cmp);//排序 
	for(int i=1;i<=n;i++){
		update(nod[i].pos);
		ans+=getsum(nod[i].pos);
	}
	cout<<ans;
	return 0;
} 

树状数组求区间最大值

hdu1754

#include<bits/stdc++.h>
using namespace std;
int h[300010];
int a[300010];int n,m; 
#define ll long long
int lowbit(int x){
	return (x&(-x));
}
void update(int x){
int ans=0;
	while(x<=n){
		h[x]=a[x];
		ans=lowbit(x);
		for(int i=1;i<ans;i<<=1){
			h[x]=max(h[x],h[x-i]);
		}
		x+=lowbit(x);
	}
	return;
}
int query(int x,int y){
	int ans=0;
	while(x<=y){
		ans=max(a[y],ans);
		y--;
		for(;y-lowbit(y)>=x;y-=lowbit(y))//
		ans=max(ans,h[y]);
	}
	return ans;
}
int main(){
	while((scanf("%d%d",&n,&m)!=EOF)){
		for(int i=1;i<=n;i++)
		h[i]=0;
		for(int i=1;i<=n;i++)
		scanf("%d",&a[i]),update(i);
		char ch;
		while(m--){
			scanf("%c",&ch);int x,y;
			scanf("%c",&ch);//空格 
			if(ch=='Q') {
				cin>>x>>y;
				int ans=query(x,y);
				printf("%d\n",ans);
			}
			else if(ch=='U'){//小心空格 
				cin>>x>>y;
				a[x]=y;//赋值 
				update(x);
			}
		}
		
	}
	return 0;
}

二维树状数组我不是很懂,毕竟没题目实践

一维拓展到二维,树状数组和差分数组

树状数组的参考博客

https://blog.youkuaiyun.com/bestsort/article/details/80796531#%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84%E5%9F%BA%E7%A1%80

看完了后,几分钟内完成了一道模板题,还是要有针对性地做,同时,要足量。

题1:https://www.luogu.org/problemnew/show/P3374

#include<bits/stdc++.h>
using namespace std;
int a[500005];int n;int maxx=-1e9;
int lowbit(int x){
	return (x&(-x));
}
void add(int i,int x){
	for(int j=i;j<=n;j+=lowbit(j)){
		a[j]+=x;
	}
	return;
}
int query(int x){
	int ans=0;
	for(int i=x;i;i-=lowbit(i)){
		ans+=a[i];
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	int m;
	
	cin>>n>>m;int x;int y,z;
	for(int i=1;i<=n;i++){
		cin>>x;
		maxx=max(maxx,x);
		add(i,x);
	}
	while(m--){
		cin>>x>>y>>z;
		if(x==1){
			add(y,z);
			
		}
		else {
			cout<<query(z)-query(y-1)<<endl;
		}
		
	}
	return 0;
} 

题2:https://www.luogu.org/problemnew/show/P3368

#include<bits/stdc++.h>
using namespace std;
int b[500005];
int a[500005];int n;int maxx=-1e9;
int lowbit(int x){
	return (x&(-x));
}
void add(int i,int x){
	for(int j=i;j<=n;j+=lowbit(j)){
		a[j]+=x;
	}
	return;
}
int query(int x){
	int ans=0;
	for(int i=x;i;i-=lowbit(i)){
		ans+=a[i];
	}
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	int m;
	
	cin>>n>>m;int x;int y,z;int k;
	for(int i=1;i<=n;i++){
		cin>>b[i];
		
	}
	for(int i=1;i<=n;i++){
		int xx=b[i]-b[i-1];//细节问题 
		add(i,xx);
	}
	while(m--){
		cin>>x>>y;
		if(x==1){
			cin>>z>>k;
			add(y,k);
			add(z+1,-k);
			
		}
		else {
			cout<<query(y)<<endl;
			
		}
		
	}
	return 0;
} 

每天根据那个ACM修炼指南看一个知识点,对应做两道题吧。在之前的计划基础上。

线段树:

需要注意的是如果是n个数,那么线段树需要开4n的空间.理论上是2n-1的空间,但是你递归建立的时候当前节点为r,那么左右孩子分别是2*r,2*r+1,此时编译器并不知道递归已结束,因为你的结束条件是在递归之前的,所以编译器会认为下标访问出错,也就是空间开小了,应该再开大2倍。有时候可能你发现开2,3倍的空间也可以AC,那只是因为测试数据并没有那么大。
原文:https://blog.youkuaiyun.com/bestsort/article/details/80815548 

总是忘。

先是对二叉树的回顾

先序+后序:不唯一确定,因为根节点单孩子情况下,先序和后序并无分别。

任何结点只有左子树的二叉树和任何结点只有右子树的二叉树,其前序序列相同,后序序列相同,但却是两棵不同的二叉树。
void preorder(tree *p){
	if(p==null){
		return;
	}
	visit(p->data);
	preorder(p->lchild);
	preorder(p->rchild);
} 

上课的时候做了一下cf,结果还有20分钟的时候,中间走来走去,反正老师不允许我上课用电脑了。

打算一旦不想写作业,想自暴自弃的时候就要打cf,剩了好多时间,以前总是无所事事。

C. Balanced Team

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are a coach at your local university. There are nn students under your supervision, the programming skill of the ii-th student is aiai.

You have to create a team for a new programming competition. As you know, the more students some team has the more probable its victory is! So you have to create a team with the maximum number of students. But you also know that a team should be balanced. It means that the programming skill of each pair of students in a created team should differ by no more than 55.

Your task is to report the maximum possible number of students in a balanced team.

Input

The first line of the input contains one integer nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of students.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109), where aiai is a programming skill of the ii-th student.

Output

Print one integer — the maximum possible number of students in a balanced team.

Examples

input

Copy

6
1 10 17 12 15 2

output

Copy

3

input

Copy

10
1337 1337 1337 1337 1337 1337 1337 1337 1337 1337

output

Copy

10

input

Copy

6
1 1000 10000 10 100 1000000000

output

Copy

1

Note

In the first example you can create a team with skills [12,17,15][12,17,15].

In the second example you can take all students in a team because their programming skills are equal.

In the third example you can create a team consisting of a single student (and you cannot create a team consisting of at least two students).

#include<bits/stdc++.h>
using namespace std;
int a[200020];
int arr[200020];int maxx=0;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		
	}
	sort(a+1,a+n+1);int j=1;
	for(int i=1;i<=n;i++){
		for(;j<=n;j++){
			if((a[j]-a[i])<=5){
				
				
				 maxx=max(maxx,j-i+1);
				
			}
			else {
			//	maxx=max(maxx,x);
				break;
			}
		//	if((x==n-i+1)) {
		//		maxx=max(maxx,x);
			//	cout<<maxx<<endl;
			//	return 0;
		//	}
		}
	}
	cout<<maxx<<endl;
	
	return 0;
	
}

超时了所以要会用下标相减表示数量。要简约。

 

 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值