ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

362. 区间

2022-08-12 17:32:11  阅读:141  来源: 互联网

标签:typedef le int 整数 long 区间 362 define


题目链接

362. 区间

给定 \(n\) 个区间 \([a_i,b_i]\) 和 \(n\) 个整数 \(c_i\)。

你需要构造一个整数集合 \(Z\),使得 \(\forall i \in [1,n]\),\(Z\) 中满足 \(a_i \le x \le b_i\) 的整数 \(x\) 不少于 \(c_i\) 个。

求这样的整数集合 \(Z\) 最少包含多少个数。

输入格式

第一行包含整数 \(n\)。

接下来 \(n\) 行,每行包含三个整数 \(a_i,b_i,c_i\)。

输出格式

输出一个整数表示结果。

数据范围

\(1 \le n \le 50000\),
\(0 \le a_i,b_i \le 50000\),
\(1 \le c_i \le b_i-a_i+1\)

输入样例:

5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1

输出样例:

6

解题思路

差分约束

设 \(x[i]\) 表示 \(i\) 这个数是否选了,则有 \(0\leq x[i]\leq 1\),\(s[i]\) 为其前缀和,要求 \(a\sim b\) 中的数不少于 \(c\) 个,即 \(s[b]-s[a]\geq c\),另外前缀和有 \(s[i]\leq s[i+1]\),由于是前缀和,而 \(a,b\) 可能为 \(0\),则所有的 \(a,b\) 都需要右移一位,根据这些不等式差分约束,求最小值即求解最长路,最后 \(s[50001]\) 即为答案

  • 时间复杂度:\(O(kn)\)

代码

// Problem: 区间
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/364/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=50005;
int n,d[N];
bool v[N];
vector<PII> adj[N];
void spfa()
{
	memset(d,-0x3f,sizeof d);
	queue<int> q;
	q.push(0);
	d[0]=0,v[0]=true;
	while(q.size())
	{
		int x=q.front();
		q.pop();
		v[x]=false;
		for(auto t:adj[x])
		{
			int y=t.fi,w=t.se;
			if(d[y]<d[x]+w)
			{
				d[y]=d[x]+w;
				if(!v[y])v[y]=true,q.push(y);
			}
		}
	}
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	int a,b,c;
    	cin>>a>>b>>c;
    	a++,b++;
    	adj[a-1].pb({b,c});
    }
    for(int i=1;i<=50001;i++)
    	adj[i].pb({i-1,-1}),adj[i-1].pb({i,0});
    spfa();
    cout<<d[50001];
    return 0;
}

标签:typedef,le,int,整数,long,区间,362,define
来源: https://www.cnblogs.com/zyyun/p/16580771.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有