您的位置:首页 > 其它

Wannafly模拟赛3-F 监视任务(贪心+线段树区间更新)

2017-10-11 19:39 423 查看
题目链接:https://www.nowcoder.com/acm/contest/13/F





题解:把所有约束按照右端点排序。

 这样每一个前面的约束区间[l1,r1],与后面的一个约束区 间[l2,r2]的交,一定为[max(l1,l2),r1]。 

对于排序后的区间依次满足约束,假设当前枚举到的约束现在没有满足,

就不断把对应区间中最右端的0改为1。 这些过程可以用线段树维护来完成。

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000
#define mod 1000000007
#define maxn 500005
#define lowbit(x) (x&-x)
#define eps 1e-9
struct node
{
int l,r,k;
}a[maxn*2];
int n,m,sum[maxn*5],lazy[maxn*5];
bool comp(node a,node b)
{
return a.r<b.r;
}
void pushdown(int l,int r,int id)
{
if(lazy[id])
{
int mid=(l+r)/2;
lazy[id*2]=1;
sum[id*2]=mid-l+1;
lazy[id*2+1]=1;
sum[id*2+1]=r-mid;
lazy[id]=0;
}
}
int update(int id,int L,int R,int l,int r,int val)
{
if(val<=0)
return 0;
if(L>=l && R<=r)
{
if(R-L+1-sum[id]<=val)
{
val-=R-L+1-sum[id];
lazy[id]=1;
sum[id]=R-L+1;
return val;
}
}
pushdown(L,R,id);
int mid=(L+R)/2;
if(r>mid)
val=update(id*2+1,mid+1,R,l,r,val);
if(l<=mid)
val=update(id*2,L,mid,l,r,val);
sum[id]=sum[id*2]+sum[id*2+1];
return val;
}
int query(int id,int L,int R,int l,int r)
{
if(L>=l && R<=r)
return sum[id];
pushdown(L,R,id);
int mid=(L+R)/2,res=0;
if(l<=mid)
res+=query(id*2,L,mid,l,r);
if(r>mid)
res+=query(id*2+1,mid+1,R,l,r);
return res;
}
int main(void)
{
int i;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k);
sort(a+1,a+m+1,comp);
for(i=1;i<=m;i++)
update(1,1,n,a[i].l,a[i].r,a[i].k-query(1,1,n,a[i].l,a[i].r));
printf("%d\n",query(1,1,n,1,n));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: