Wannafly模拟赛3-F 监视任务(贪心+线段树区间更新)
2017-10-11 19:39
423 查看
题目链接:https://www.nowcoder.com/acm/contest/13/F
![](https://img-blog.csdn.net/20171011194422721)
![](https://img-blog.csdn.net/20171011194432436)
题解:把所有约束按照右端点排序。
这样每一个前面的约束区间[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;
}
题解:把所有约束按照右端点排序。
这样每一个前面的约束区间[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;
}
相关文章推荐
- Wannafly模拟赛3 监视任务(贪心+线段树)
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
- FZU 1608 Huge Mission (线段树区间更新 + 贪心)
- poj 1201 interval 差分约束/贪心+线段树区间更新
- poj 3468(简单线段树区间更新)
- POJ 3468 A Simple Problem with Integers(线段树 区间更新)
- hdu 1698 线段树区间更新
- HDU 1166-敌兵布阵(线段树:单点更新,区间求和)
- poj-3468-线段树,区间更新
- 线段树第二弹!SHU1973 鸡排销售查询系统(区间更新+Lazy)
- poj 2528 线段树离散化+区间更新
- poj 1823 Hotel(数据结构:线段树--区间更新)
- HDU1968 线段树区间更新
- hdu 1566 Color the ball(线段树区间更新)
- hdu 5239 区间平方 线段树区间更新
- 区间最小值(2) (线段树 更新区间)2015年 JXNU_ACS 算法组暑假第一次周赛
- Billboard(线段树区间更新与求值)
- POJ3468 区间更新+区间查询(线段树)
- poj3468 A Simple Problem with Integers 线段树 区间更新 lazy
- 线段树 区间更新模板