Daliyアルゴリズム(バイナリ) - 53日

恐れることは何もありません

あなたは早起きして、あなたが懸命に働くそれらの時。あなたは夜更かしして、懸命に働くそれらの時。当時は作業のように感じていない場合 - あなたはあまりにも疲れている、あなたは自分自身をプッシュする必要はありません - しかし、あなたはとにかくそれを行います。それは実際には夢です。それは夢です。それは旅だ、目的地ではありません。あなたたちはそれを理解することができればと、何が起こる参照してくださいよと、あなたがあなたの夢を達成しないことを、あなたの夢が叶うません、何か大きな意志です。マンバアウト


あなたが疲れを感じるが、それでも夢を追いかけて、おそらくあなたができない、何があっエンドのプロセスを楽しむために道を気にしないことをするとき、歯に付着していたときに、予備のハードワークを支払うものは、あなたが、訓練する必要はありません成功を夢見たが、後に続く多くの素晴らしいものがあるでしょう。マンバアウト〜

2020年4月9日


基盤を築くためにあなたの時間をかけて

トリプルインクリメント

溶液の半分に到達することができます\(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三次方程式ソルバー

実際のドメイン二部:考える
2以上の言った根の差の絶対値よりますが、タイトルをまたは1に等しい
私たちは間の答えを検索する必要がありますので(私は、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;
}

配列セグメントLG-p1182

思考:+貪欲バイナリ
客観体は最小の最大値を見つけることである:
1.二部のアイデアは、単調なシーケンスの答えがでなければならない
ことは、アレイの左境界の最小値の最大値が間に大きなグループでなければなりませんので、2全て及びr =の1つの別個のパケットとして

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;
}

おすすめ

転載: www.cnblogs.com/wlw-x/p/12670250.html