牛客_糖糖问题_差分_代码详解_小白能听的懂的差分

前言

这道题是一道水题
我把这道题写出来是因为,当时我看题的时候犯二了。
题目说从第i秒的时候,第i只糖糖就可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的糖糖。
我以为是像是比如第二秒的时候 看看第二个能不能消灭前面的人,第三秒时,第三个人…
其实不是,好像是,n秒之后再看能不能消灭。

用差分可以把时间复杂度从N2 降到N

糖糖名字好可爱

差分讲解

以此题举例
糖糖的爸爸,娇姐,会发功m次,第i次发功的时间为ci,则在第ci秒结束后,b1,b2,…,bci都会增加1.
正常用暴力来解的话,时间复杂度为 ci1+ci2+ci3+……+cim 需要用到两层循环时间复杂度大致为N2

用差分那,需要新建一个数组,初始化为0,这里面存着功力增加值,但是每次修改,只需要修改两端的数值 ci[1],ci[x+1].。这个区间的每个元素都需要+1,所以这个区间前后两值的差是不变的。
最后只需要 ci[1]=ci[1]+ci[0],ci[2]=ci[2]+ci[1]…这么循环走一遍就可以知道第i个糖糖增加的功力。
这样只需要一层循环就可以完成任务。

题目

链接:https://ac.nowcoder.com/acm/problem/14583
来源:牛客网

题目描述

从前,有n只萌萌的糖糖,他们分成了两组一起玩游戏。他们会排成一排,第i只糖糖会随机得到一个能力值bi。从第i秒的时候,第i只糖糖就可以消灭掉所有排在他前面的和他不是同一组的且能力值小于他的糖糖。

为了使游戏更加有趣,糖糖的爸爸,娇姐,会发功m次,第i次发功的时间为ci,则在第ci秒结束后,b1,b2,…,bci都会增加1.

现在,娇姐想知道在第n秒后,会有多少只糖糖存活下来。
输入描述:

第一行只有一个整数T(T<6),表示测试数据的组数。
第二行有两个整数n,m。表示糖糖的个数以及娇姐发功的次数。(1<=n<=50000,1<=bi<=1000000)
第三行到n+2行,每行有两个整数ai,bi,表示第i只糖糖属于那一组以及他的能力值。(0<=ai<=1,1<=bi<=1000000)
第n+3行到第n+m+2行,每行有一个整数ci,表示GTW第i次发功的时间.(1<=ci<=n)

输出描述:

总共T行,第i行表示第i组数据中,糖糖存活的个数。
eg:
代码

#include <bits/stdc++.h>
using namespace std;
int ai[50010],bi[50010],ci[50010];
int n,m;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		memset(ci,0,sizeof ci);//注意ci要清0
		for(int i=1;i<=n;i++)
			cin>>ai[i]>>bi[i];
		for(int i=1;i<=m;i++)
			{
			int x;
			cin>>x;
			ci[1]++;
			ci[x+1]--;
			}//差分
		for(int i=1;i<=n;i++)
		{
			ci[i]+=ci[i-1],bi[i]+=ci[i];
		}
		int max0=-1,max1=-1;
		int cns=0;
		for(int i=n;i>=1;i--)
		{
			if(ai[i]==0)
			{
				max0=max(max0,bi[i]);
			}
			else
			{
				max1=max(max1,bi[i]);
			}
			if(ai[i]==0&&bi[i]>=max1) cns++; 
			if(ai[i]==1&&bi[i]>=max0) cns++; 
		}
		cout<<cns<<endl;
	}
	return 0;
}

原创文章 12 获赞 11 访问量 404

猜你喜欢

转载自blog.csdn.net/FRANK48691/article/details/106143114