Daliy Algorithm (binary) - day 53

Nothing to fear

those times when you get up early and you work hard; those times when you stay up late and you work hard; those times when don’t feel like working — you’re too tired, you don’t want to push yourself — but you do it anyway. That is actually the dream. That’s the dream. It’s not the destination, it’s the journey. And if you guys can understand that, what you’ll see happen is that you won’t accomplish your dreams, your dreams won’t come true, something greater will. mamba out


Those spare your hard work pay, you do not want to train, when you feel tired but still have to adhere to teeth when that chasing a dream, do not care what the end there, the road to enjoy the process, perhaps you can not dream of success, but there will be more great things will follow. mamba out ~

2020.4.9


Take your time to lay the foundation

Increment triple

Half of the solution can be reached \ (O (nlogn) \)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>

using namespace std;
typedef long long ll;
const int N = 100005;
int A[N] , B[N] , C[N] ;
int sum[N] , n;
ll ans;
void init()
{
	cin >> n;
	for(int i = 0;i < n ;i ++)scanf("%d",&A[i]);
	for(int i = 0;i < n ;i ++)scanf("%d",&B[i]);
	for(int i = 0;i < n ;i ++)scanf("%d",&C[i]);

	sort(A , A + n);
	sort(C , C + n);
	sort(B , B + n);
}


int main()
{
	init();
	for(int i = 0;i < n ;i ++)
	{
		//找到A中第一个大于等于B[i]的元素/最后一个小于等于B[i]的坐标
		int l = 0 , r = n - 1;
		while(l < r)
		{
			int mid = l + r + 1 >> 1;
			if(A[mid] < B[i])l = mid;
			else r = mid - 1;
		}
		int t = 0;
		if(A[l] >= B[i])l = -1;
		t = l;
		l = 0, r = n - 1;
		while(l < r)
		{
			int mid = l + r >> 1;
			if(C[mid] > B[i])r = mid;
			else l = mid + 1;
		}
		if(B[i] >= C[r])r = n;
		int right = r;
		ans += (ll)(n - right ) * (t + 1);
	}
	cout << ans << endl;
	return 0;
}

lg-p1024 Cubic equation solver

Thinking: real domain bipartite
but title absolute difference between said root of two greater than or equal to 1
so we should search for an answer between (i, i + 1)

判断划分区间是否存在根只需要判断
l - mid : f(l) * f(mid) < 0  // 根在左边区间
mid - r :  f(r) * f(mid) < 0  // 根在右边区间
由于判断根重复所以 f(l) 和 f(r) 只需要判断一个即可
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>

using namespace std;
double a , b , c , d;
int s = 0 , t1 , t2;
double f(double x)
{
	return a*(x*x*x) + b*x*x + c*x + d; 
}
void bs(double l, double r)
{
	if(r - l <= 0.001){
		printf("%.2f ",l);
		return;
	}
	double mid = (l + r) / 2;
	double ansl , ansr;
	ansl = f(l) * f(mid);
	ansr = f(r) * f(mid);
	if(f(mid) == 0)printf("%.2f ",mid);
	if(f(r) == 0)printf("%.2f ",r);
	if(ansl < 0)bs(l , mid);
	else if(ansr < 0)bs( mid , r);
}
int main()
{
	cin >> a >> b >> c >> d;
	for(int i = -100 ;i <= 99 ;i ++)
	{
		if(f(i) * f(i + 1.0) <= 0)
			bs(i , i + 1.0);
	}
	return 0;
}

Sequence segments lg-p1182

Thinking: + greedy binary
objective body is to find the minimum maximum values:
1. bipartite idea must be a monotonic sequence answer is
2. Since it is the minimum maximum values of the left boundary of the array must be large groups among as a separate packet which one of all and r =

3. check() 条件采用贪心的思路 : 
如果当前分组满足二分的当前答案就持续分
如果拿到下一个数不满足当前二分的最大值就划分
最后判断分组的个数是否合法 如果合法就让 r = mid
否则 l = mid + 1
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>

using namespace std;
const int N = 1000005;
int n , m , l , r;
int a[N];
bool check(int x)
{
	int sum = 0 , cnt = 0;
	for(int i = 1;i <= n ;i ++)
	{
		if(sum + a[i] <= x)sum += a[i];
		else sum = a[i],cnt++;
	}
	return cnt + 1 <= m;
}

int main()
{
	int x = 0;
	cin >> n >> m;
	for(int i = 1;i <= n ;i ++)
	{
		scanf("%d",&a[i]);
		r += a[i];l = max(l , a[i]);
	}
	//确保答案一定在这个区间
	while(l < r)
	{
		int mid = l + r >> 1;
		if(check(mid))r = mid;
		else l = mid + 1;
	}
	cout << l << endl;
	return 0;
}

Guess you like

Origin www.cnblogs.com/wlw-x/p/12670250.html