树状数组(Binary Indexed Tree)

树状数组

应用:

1.修改单个数询问区间和。

2.整个区间加(即整个区间每个数都修改),然后去查单点的值。——》差分

树状数组 模板:

修改单个数询问区间和

// 固定的三个函数

ll lowbit(ll x)
{
	return x&(-x); 
}

void add(ll i, ll val)
{// 对c[i]加val,对管辖它的每个数都加val,譬如对 c[1]加1,则对c[2]c[4]c[8]都要加1 
	while(i <= n)
	{
		c[i] += val;
		i += lowbit(i);
	}
}

ll sum(ll i)  // 求前i个数的和 // 区间和就相减咯 
{
	ll s = 0;
	while(i > 0)
	{
		s += c[i];
		i -= lowbit(i);  // 减掉它管辖的区域 // lowbit(i)就是求出它管辖区域的元素个数 
	}
	return s;
}

// 练练手:
https://www.luogu.com.cn/problem/P3374

// 树状数组
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N = 1e6;
ll n, m, opt, t, t1, t2, c[N];

ll lowbit(ll x)
{
	return x&(-x); 
}

void add(ll i, ll val)
{// 对c[i]加val,对管辖它的每个数都加val,譬如对 c[1]加1,则对c[2]c[4]c[8]都要加1 
	while(i <= n)
	{
		c[i] += val;
		i += lowbit(i);
	}
}

ll sum(ll i)  // 求前i个数的和 // 区间和就相减咯 
{
	ll s = 0;
	while(i > 0)
	{
		s += c[i];
		i -= lowbit(i);  // 减掉它管辖的区域 // lowbit(i)就是求出它管辖区域的元素个数 
	}
	return s;
}

int main()
{
	scanf("%d%d",&n,&m);
	for(ll i = 1; i <= n; i++)
	{
		scanf("%d",&t);
		add(i, t); // 构造过程 等同于 添加过程 
	}
	for(ll i = 1; i <= m; i++)
	{
		scanf("%d%d%d",&opt,&t1,&t2);
		if(opt == 1)
			add(t1, t2);
		else
			printf("%d\n",sum(t2)-sum(t1-1));  // 这里不必判断t1-1是否会为0啥的 
	}
	return 0;
}

修改整个区间,查单点——》差分

差分讲解

总结:差分实现了**“修改区间”——》“修改单点”“查单点”——》查前缀和**

练手题:洛谷-P3368 【模板】树状数组 2

参考代码:

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int N=5e5+1;
ll n,m,a[N],c[N];

inline ll lowbit(ll x)
{
	return x&(-x);
}

void add(ll i,ll val)
{
	while(i<=n)
	{
		c[i]+=val;
		i+=lowbit(i);
	}
}

ll sum(ll i)
{
	ll s=0;
	while(i>0)
	{
		s+=c[i];
		i-=lowbit(i);
	}
	return s;
}

int main()
{
	scanf("%lld %lld",&n,&m);
	for(int i=1;i<=n;++i) 
	{
		scanf("%lld",&a[i]);	
		add(i,a[i]-a[i-1]);
	}
	ll opt,x,y,z;
	while(m--)
	{
		scanf("%lld",&opt);
		if(opt==1)
		{
			scanf("%lld %lld %lld",&x,&y,&z);
			add(x,z);
			add(y+1,0-z);
		}
		else 
		{
			scanf("%lld",&x);
			printf("%lld\n",sum(x));
		}
	}
}

树状数组——维护区间最值

最大数maxnumber

两种操作:
1.末尾插入一个元素
2.查询当前数列中末尾L个数中的最大的数

参考博客:(2条消息) 树状数组之区间最值_想谈恋爱的范德川的博客-CSDN博客_树状数组维护区间最值

参考代码:
树状数组做法:

#include <bits/stdc++.h>
using namespace std;

const int N=2e5+5;
int m,mod,t,a[N],len,last;
char ch;
int c[N];

inline int lowbit(int x)
{
	return x&(-x);
}

//求区间最值:
int query(int x,int y){
	int ans=0;
	while(x<=y)
	{
		ans=max(ans,a[y]),--y; //x在y的管辖区域里 
		while(y-lowbit(y)>=x){ //x不在y的管辖区域内 
			ans=max(ans,c[y]);
			y-=lowbit(y);
		}
	}
	return ans;
} 

int main()
{
	scanf("%d %d",&m,&mod);getchar(); //输入字符之前getchar()一下 
	while(m--)
	{
		scanf("%c %d",&ch,&t);
		if(ch=='A')
		{
			a[++len]=(t+last)%mod;
			c[len]=max(query(len-lowbit(len)+1,len-1),a[len]); //c[pos]维护它管辖区域的最值 
		}
		else
			printf("%d\n",last=query(len-t+1,len));
		getchar(); //输入字符之前getchar()一下
	}
	return 0; 
}

单调栈做法://单调栈可以维护 末尾一段元素最大值

#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int N=2e5+10;
int m,mod,last,t,st[N],top,a[N],len,pos;
char c;

int main()
{
	scanf("%d %d",&m,&mod); getchar();
	for(int i=1;i<=m;++i)
	{
		scanf("%c %d",&c,&t);
		if(c=='A')
		{
			t=(t+last)%mod;
			a[++len]=t;
			while(top&&a[st[top]]<=t) top--;
			st[++top]=len;
		}
		else
		{
			pos=lower_bound(st+1,st+1+top,len-t+1)-st;
			printf("%d\n",a[st[pos]]);
			last=a[st[pos]];
		}
		getchar();
	}
} 

类似题目:
管家的忠诚

//维护区间最小值

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int m,n,a[N],c[N];

inline int lowbit(int x)
{
	return x&(-x);
}

int qry(int x,int y)
{
	int ans=INT_MAX;
	while(x<=y)
	{
		ans=min(ans,a[y]),--y;
		while(y-lowbit(y)>=x)
		{
			ans=min(ans,c[y]);
			y-=lowbit(y);
		}
	}
	return ans;
}

int main()
{
	scanf("%d %d",&m,&n);
	for(int i=1;i<=m;++i) 
	{
		scanf("%d",&a[i]);
		if(i==1) c[i]=a[i];
		else c[i]=min(qry(i-lowbit(i)+1,i-1),a[i]);	
	}
	int x,y;
	while(n--)
	{
		scanf("%d %d",&x,&y);
		printf("%d",qry(x,y));
		if(n==0) printf("\n");
		else printf(" ");
	}
}

逆序对

暴力做法:
时间复杂度: O ( N 2 ) O(N^2) O(N2)
优点: O ( 1 ) O(1) O(1)访问任意区间的逆序对数
逆序对计数

#include <bits/stdc++.h> 
using namespace std;

#define int long long
const int N=6e3+3;
int n,q,a[N],f[N][N];

signed main(){
	scanf("%lld",&n);
	for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
	for(int i=1;i<=n;++i){
		int s=0;
		for(int j=i-1;j>=1;--j){
			if(a[i]<a[j]) s++;
			f[j][i]=f[j][i-1]+s;
		}
	} 
	scanf("%lld",&q);
	int l,r;
	while(q--) {
		scanf("%lld%lld",&l,&r);
		printf("%lld\n",f[1][n]+(r-l)*(r-l+1)/2-2*f[l][r]);
	}
}

归并排序做法
------------------------------2023.3.30 更新--------------------------

归并排序

//辅助数组 
int b[N];
//merge()函数功能:将有序表A[low...mid]和A[mid+1...high]合并为一个有序表 
void merge(int a[],int low,int mid,int high){
	int i,j,k;
	for(k=low;k<=high;++k) b[k]=a[k];
	for(i=low,j=mid+1,k=low;i<=mid&&j<=high;++k){
		if(b[i]<=b[j]){
			a[k]=b[i];++i;
		}else {
			a[k]=b[j];++j;
		}
	}
	while(i<=mid) {
		a[k]=b[i];++k;++i;
	}
	while(j<=high) {
		a[k]=b[j];++k;++j;
	}
}

void mergesort(int a[],int low,int high){
	if(low<high){ //特别注意这句是小于不是小于等于!因为左子树取的是[low,mid]
		int mid=((low+high)>>1);
		mergesort(a,low,mid);
		mergesort(a,mid+1,high);
		merge(a,low,mid,high);
	}
}

练手题:洛谷 P1908 逆序对
参考代码:

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=5e5+5;
int n,a[N],b[N],ans=0;

void merge(int a[],int low,int mid,int high){
	int i,j,k;
	for(k=low;k<=high;++k) b[k]=a[k];
	for(i=low,j=mid+1,k=low;i<=mid&&j<=high;++k){
		if(b[i]<=b[j]){
			a[k]=b[i];++i;
		}else {
			a[k]=b[j];++j;
			ans+=(mid-i+1);
		}
	}
	while(i<=mid) {
		a[k]=b[i];++k;++i;
	}
	while(j<=high) {
		a[k]=b[j];++k;++j;
	}
}

void mergesort(int a[],int low,int high){
	if(low<high){
		int mid=((low+high)>>1);
		mergesort(a,low,mid);
		mergesort(a,mid+1,high);
		merge(a,low,mid,high);
	}
}

signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i) cin>>a[i];	
	mergesort(a,1,n);
	cout<<ans<<'\n';
}

--------------------旧版代码:自我觉得可读性不高。。。

/*
归并排序有个特点:前一个大于后一个的才交换。 
*/ 
#include <iostream>
using namespace std;

int r[1000005], rs[1000005], n;
long long num;
void mergesort(int *a, int *b, int x, int y);

int main()
{
	scanf("%d",&n);                   // 输入 
	for(int i = 1; i <= n; i++)
		scanf("%d",&r[i]);
	mergesort(r, rs, 1, n);
	printf("%lld\n",num);
	return 0;
}

/*
参数说明:a为原数组,b为辅助数组,排序范围为 [x, y]
函数功能说明:使用归并排序算法使 a 数组有序 
参考书籍:刘汝佳《算法竞赛入门经典(第二版)》
*/ 
void mergesort(int *a, int *b, int x, int y)
{
	// 没有返回值,当x=y不必做任何操作(当个元素即有序!) 
	if(y > x)
	{
		int mid = (x + y) / 2;  // 划分 
		int l = x, h = mid + 1, i = x;  // 这个是算法细节! l记左序列,h记右序列,i记总序列 
		mergesort(a, b, x, mid);  // 归并排序左边 
		mergesort(a, b, mid + 1, y);  // 归并排序右边 
		while(l <= mid || h <= y)  // 归并左右两个有序序列 
		{
			if(h > y || (l <= mid && a[l] <= a[h]))  // 技巧:巧妙利用"||"(短路运算符)把两个条件链接起来:如果条件1满足,不会计算条件2;如果条件1不满足,就一定会计算条件2 
				b[i++] = a[l++];  // 提示:要熟悉这种写法,复制后移动下标。
			else
			{
				num += mid - l + 1;
				b[i++] = a[h++];
			}
		}
		for(i = x; i <= y; i++) // 将归并的结果(存在辅助数组 b 中)复制到 a 中 
			a[i] = b[i];
	}
}

树状数组做法:
时间复杂度: O ( N l o g N ) O(NlogN) O(NlogN)
优点:适合于数据量比较大的情况。
缺点:只能一次统计数组中的逆序对数量。

逆序对
统计数组中的逆序对数量,可能有重复元素
参考代码:

#include <bits/stdc++.h>
using namespace std;

const int N=1e6+5;
int n,a[N],b[N],c[N];

inline int lowbit(int x){
	return x&-x;
}

void update(int id,int val) //在id号点加上val
{
	while(id<=n){
		c[id]+=val;
		id+=lowbit(id);
	} 
} 

int sum(int id) {
	int ans=0;
	while(id>0) {
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&a[i]);
		b[i]=a[i];
	}
	//离散化——排序、去重、找位置 
	sort(b+1,b+1+n);
	int d=unique(b+1,b+1+n)-b-1; //元素个数 
	a[0]=-1;
	long long ans=0;
	for(int i=1;i<=n;++i){
		int pos=lower_bound(b+1,b+1+d,a[i])-b;
		update(pos,1); 
		ans+=(i-sum(pos)); //减去小于等于这个点的点 
	} 
	printf("%lld\n",ans); 
} 

好题:
火柴排队(逆序对变形)
有长度为 n n n a , b a,b a,b两个数组,每个数组中任意相邻两个数的位置都可以交换。问要使得 ∑ i = 1 n ( a i − b i ) 2 \sum_{i=1}^{n} (a_{i}−b_{i})^2 i=1n(aibi)2最小的最少交换次数。其实就是求一个数列的逆序对数量。

参考博客:(2条消息) NOIp2013提高组 火柴排队————逆序对+贪心_wly127的博客-CSDN博客

#include <bits/stdc++.h>
using namespace std;

const int N=1e5+10;
const int MOD=99999997;
#define pii pair<int,int>
#define pb push_back
#define se second
#define fi first
#define ll long long
vector<pii> a,b;
int n,num[N],t,c[N];
ll ans;

bool cmp(pii x,pii y)
{
	return x.fi<y.fi;
}

inline int lowbit(int x)
{
	return x&(-x);
}

void update(int id,int val)
{
	while(id<=n)
	{
		c[id]+=val;
		id+=lowbit(id);
	}
}

int sum(int id)
{
	int ans=0;
	while(id>0)
	{
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) 
	{
		scanf("%d",&t);
		a.pb({t,i});
	}
	for(int i=1;i<=n;++i) 
	{
		scanf("%d",&t);
		b.pb({t,i});
	}
	sort(a.begin(),a.end(),cmp);
	sort(b.begin(),b.end(),cmp);
	for(int i=1;i<=n;++i)
		num[a[i-1].se]=b[i-1].se;
	for(int i=1;i<=n;++i) //统计num中的逆序对 
	{
		update(num[i],1);
		ans+=(i-sum(num[i])); //树状数组求逆序对操作~ 
		ans%=MOD;
	}
	printf("%lld\n",ans);
}

好题:2019河北省大学生程序设计竞赛 E-Paper Plane Fly Away
题意:给定一个数 n n n ,接下来给出 n n n 行,每行两个整数,分别代表坐在第 i i i 号男生前面的女生的下标和第 i i i 号男生喜欢的女生的下标。每个男生都要给自己喜欢的女生传纸飞机(直线传送)。问每个男生在传纸飞机时会被多少架其他纸飞机撞到。
思路:
1.对于样例,就是以下这么一幅图:

在这里插入图片描述

然后求每条线的交点数。

2.线 l l l 会和线 l 1 l_1 l1 产生交点,当且仅当 ( l 1 l_1 l1 的起点在 l l l 的左边&& l 1 l_1 l1 的终点在 l l l 的右边) || ( l 1 l_1 l1 的起点在 l l l 的右边&& l 1 l_1 l1 的终点在 l l l 的左边) 。

3.考虑用树状数组插入点(思想 重要),正着扫一遍,反着扫一遍,可以求出答案。

代码:

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=1e5+5;
int n,a[N],b[N],l[N],c[N],cnt[N];

inline int lowbit(int x){
	return x&-x;
}

void add(int id,int val){
	while(id<=n){
		c[id]+=val;
		id+=lowbit(id);
	}
}

int sum(int id){
	int ans=0;
	while(id>0){
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}

signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	int t1,t2;
	for(int i=1;i<=n;++i){
		cin>>t1>>t2;
		a[i]=t2-n;
		b[t1-n]=i;
	}
	for(int i=1;i<=n;++i) l[i]=b[a[i]]; //第i号男孩喜欢的女孩坐在什么位置

	//正着扫一遍
	for(int i=0;i<=n;++i) c[i]=0;
	for(int i=1;i<=n;++i){
		cnt[i]+=sum(n)-sum(l[i]);
		add(l[i],1);
	}
	//反着扫一遍 
	for(int i=0;i<=n;++i) c[i]=0;
	for(int i=n;i>=1;--i){
		cnt[i]+=sum(l[i]-1);
		add(l[i],1);
	}
	
	for(int i=1;i<=n;++i) cout<<cnt[i]<<'\n';
}

离线处理+树状数组

统计区间种类数

HH的项链

参考博客

#include <bits/stdc++.h>
using namespace std;

const int N=5e4+10;
struct Node{
	int l,r,i;
}q[200005];
int n,m,a[N],c[N],vis[1000007],ans[200005];

bool cmp(Node x,Node y)
{
	return x.r<y.r;
}

inline int lowbit(int x)
{
	return x&(-x);
}

void add(int id,int val)
{
	while(id<=n)
	{
		c[id]+=val;
		id+=lowbit(id);
	}
}

int sum(int id)
{
	int ans=0;
	while(id>0)
	{
		ans+=c[id];
		id-=lowbit(id);
	}
	return ans;
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) 
		scanf("%d",&a[i]);
	scanf("%d",&m);
	for(int i=1;i<=m;++i)
	{
		scanf("%d %d",&q[i].l,&q[i].r);
		q[i].i=i;
	}
	sort(q+1,q+1+m,cmp);
	int j=1;
	for(int i=1;i<=m;++i)
	{
		while(j<=q[i].r)
		{
			if(vis[a[j]]) add(vis[a[j]],-1); //把前面的记录删了~~ 
			add(j,1);
			vis[a[j]]=j;
			++j;
		}
		ans[q[i].i]=sum(q[i].r)-sum(q[i].l-1);
	}
	for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
}

采花
查询[l,r]区间内出现至少两次的元素种类

#include <bits/stdc++.h>
using namespace std;

#define io(x) scanf("%d",&x);
const int N=1e6+6;
int n,k,m,a[N],c[N],ans[N],vis[N],cnt[N],last[N];

struct Node{
	int l,r,id;
}q[N];

bool cmp(Node x,Node y)
{
	return x.r<y.r;
}

inline int lowbit(int x)
{
	return x&(-x);
}

void add(int id,int val)
{
	while(id<=n)
	{
		c[id]+=val;
		id+=lowbit(id);
	}
}

int sum(int id)
{
	int s=0;
	while(id>0)
	{
		s+=c[id];
		id-=lowbit(id);
	}
	return s;
}

int main()
{
	io(n);io(k);io(m);
	for(int i=1;i<=n;++i) io(a[i]);
	for(int i=1;i<=m;++i) 
	{
		io(q[i].l);
		io(q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp);
	int j=1;
	for(int i=1;i<=m;++i)
	{
		while(j<=n && j<=q[i].r)
		{
			cnt[a[j]]++;
			if(cnt[a[j]]>=2)
			{
				if(last[a[j]]) add(last[a[j]],-1); //把上上一个位置除掉 
				add(vis[a[j]],1); //在上一个点的位置加1
				last[a[j]]=vis[a[j]];  
			}
			vis[a[j]]=j;//修改为当前的点
			++j;
		}
		ans[q[i].id]=sum(q[i].r)-sum(q[i].l-1);
	}
	for(int i=1;i<=m;++i)
		printf("%d\n",ans[i]);
} 

配对统计

配对统计

参考博客

/*
配对统计
离线查询
1.先把对统计出来
2.对查询右端点排序,对 成对 的右端点排序
*/

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define fi first
#define se second
#define pii pair<int,int>
#define ll long long 
const int N=3e5+5;
vector<pii> a,couple;
int n,m,c[N];
ll ans=0;

bool cmp(pii x,pii y)
{
	return x.fi<y.fi;
}

struct Node{
	int l,r,id;
}q[N];

bool cmp1(Node x,Node y)
{
	return x.r<y.r;
}

inline int lowbit(int x)
{
	return x&(-x);
}

void add(int id,int val)
{
	while(id<=n)
	{
		c[id]+=val;
		id+=lowbit(id);
	}
}

int qry(int id)
{
	int sum=0;
	while(id>0)
	{
		sum+=c[id];
		id-=lowbit(id);
	}
	return sum;
}

bool cmp2(pii x,pii y)
{
	return x.se<y.se;
}

int main()
{
	scanf("%d %d",&n,&m);
	int t;
	for(int i=1;i<=n;++i) 
	{
		scanf("%d",&t);
		a.pb({t,i});
	}
	for(int i=1;i<=m;++i)
	{
		scanf("%d %d",&q[i].l,&q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp1);
	sort(a.begin(),a.end(),cmp);
	if(n==1){
		cout<<0<<endl;
		return 0;	
	}
	for(int i=0;i<a.size();++i)
	{
		int t1,t2;
		if(i==0)
		{
			t1=a[i].se,t2=a[i+1].se;
			if(t1>t2) swap(t1,t2);
			couple.pb({t1,t2});	
		}
		if(i==a.size()-1)
		{
			t1=a[i-1].se,t2=a[i].se;
			if(t1>t2) swap(t1,t2);
			couple.pb({t1,t2});		
		}
		if(i!=0 && i!=a.size()-1)
		{
			if(abs(a[i].fi-a[i-1].fi)<=abs(a[i].fi-a[i+1].fi))
			{
				t1=a[i-1].se,t2=a[i].se;
				if(t1>t2) swap(t1,t2);
				couple.pb({t1,t2});	
			} 
			if(abs(a[i].fi-a[i-1].fi)>=abs(a[i].fi-a[i+1].fi))
			{
				t1=a[i].se,t2=a[i+1].se;
				if(t1>t2) swap(t1,t2);
				couple.pb({t1,t2});	
			}
		}
	}
	sort(couple.begin(),couple.end(),cmp2);
//	cout<<couple.size()<<endl;
	int j=0;
	for(int i=1;i<=m;++i) //遍历需求
	{
		while(j<couple.size() && couple[j].se<=q[i].r)
		{
			add(couple[j].fi,1);
			++j;
		}
		ans+=(long long)(q[i].id)*(long long)(qry(q[i].r)-qry(q[i].l-1));
	} 
	printf("%lld\n",ans);
}

找规律+树状数组

异或橙子

参考博客

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N=2e5+5;
int n,m,c1[N],c2[N],a[N];

inline int lowbit(int x)
{
	return x&-x;
}

int sum1(int id)
{
	int sum=0;
	while(id>0)
	{
		sum^=c1[id];
		id-=lowbit(id); 
	}
	return sum;
}

int sum2(int id)
{
	int sum=0;
	while(id>0)
	{
		sum^=c2[id];
		id-=lowbit(id);
	}
	return sum;
}

void add1(int id,int val)
{
	while(id<=n)
	{
		c1[id]^=val;
		id+=lowbit(id);
	}
}

void add2(int id,int val)
{
	while(id<=n)
	{
		c2[id]^=val;
		id+=lowbit(id);
	}
}

signed main(void)
{
	scanf("%lld %lld",&n,&m);
	int t;
	for(int i=1;i<=n;++i)
	{
		scanf("%lld",&a[i]);
		if(i%2) add1(i,a[i]);
		else add2(i,a[i]);
	}
	int opt,x,y;
	while(m--)
	{
		scanf("%lld %lld %lld",&opt,&x,&y);
		if(opt==1)
		{
			if(x%2)
			{
				add1(x,a[x]);
				add1(x,y);
				a[x]=y;//要修改一下!!! 
			}
			else
			{
				add2(x,a[x]);
				add2(x,y);
				a[x]=y;//要修改一下!!!
			}
		}
		else
		{
			if(x>y) swap(x,y);
			if(x%2 && y%2)
			{
				printf("%lld\n",sum1(y)^sum1(x-1));
			}
			else if(x%2==0 && y%2==0)
			{
				printf("%lld\n",sum2(y)^sum2(x-1));
			}
			else
				printf("0\n");
		}
	}
}
  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值