Description
You are given n closed, integer intervals [ai, bi] and n integers c1,
…, cn. Write a program that: reads the number of intervals, their
end points and integers c1, …, cn from the standard input, computes
the minimal size of a set Z of integers which has at least ci common
elements with interval [ai, bi], for each i=1,2,…,n, writes the
answer to the standard output. InputThe first line of the input contains an integer n (1 <= n <= 50000) –
the number of intervals. The following n lines describe the intervals.
The (i+1)-th line of the input contains three integers ai, bi and ci
separated by single spaces and such that 0 <= ai <= bi <= 50000 and 1
<= ci <= bi - ai+1. OutputThe output contains exactly one integer equal to the minimal size of
set Z sharing at least ci elements with interval [ai, bi], for each
i=1,2,…,n.
差分约束系统。
对于a[i..j]>=c,利用前缀和优化成s[j]-s[i-1]>=c,就可以用差分约束系统了。
注意本题的特殊性,还应该加上限制条件s[i]>=s[i-1],s[i]<=s[i-1]+1。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int dis[50010],fir[50010],ne[200010],to[200010],len[200010];
queue<int> q;
void add(int num,int f,int t,int l)
{
ne[num]=fir[f];
fir[f]=num;
to[num]=t;
len[num]=l;
}
int main()
{
int i,j,k,m,n,p,x,y,z,ans=0,u,v;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(i,y,x-1,-z);
}
for (i=1;i<=50000;i++)
{
add(i*2+n,i,i-1,0);
add(i*2+1+n,i-1,i,1);
}
for (i=0;i<=50000;i++)
q.push(i);
while (!q.empty())
{
u=q.front();
q.pop();
for (i=fir[u];i;i=ne[i])
{
v=to[i];
if (dis[u]+len[i]<dis[v])
{
dis[v]=dis[u]+len[i];
q.push(v);
}
}
}
for (i=0;i<=50000;i++)
ans=max(ans,-dis[i]);
printf("%d\n",ans);
}