#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 1000
#define inf 1000000
using namespace std;
class segtree
{
public:
int val,addmark;
};
segtree segt[maxn<<2];
int a[maxn];
void build(int root,int beg,int en)
{
if (beg==en)
{segt[root].val=a[beg];segt[root].addmark=0;return;}
else
{
int mid=(beg+en)/2;
build(root*2,beg,mid);
build(root*2+1,mid+1,en);
}
segt[root].val=min(segt[root*2].val,segt[root*2+1].val);//改这里
segt[root].addmark=0;
}
void pushdown(int root)
{
if (segt[root].addmark!=0)
{
segt[root*2].val+=segt[root].addmark;
segt[root*2].addmark+=segt[root].addmark;
segt[root*2+1].val+=segt[root].addmark;
segt[root*2+1].addmark+=segt[root].addmark;
segt[root].addmark=0;
}
return;
}
void update(int root,int rst,int ren,int beg,int en,int val)//update是加上一个数,如果是变成一个数,那就需要改update
{
if (rst>=beg&&ren<=en)
{
segt[root].val+=val;
segt[root].addmark+=val;
}
else if (rst>en||ren<beg) {return;}
else
{
pushdown(root);
int mid=(rst+ren)/2;
update(root*2,rst,mid,beg,en,val);
update(root*2+1,mid+1,ren,beg,en,val);
segt[root].val=min(segt[root*2].val,segt[root*2+1].val);//改这里
}
}
int query(int root,int rst,int ren,int beg,int en)
{
if (rst>en||ren<beg)
return inf;//改这里
if (rst==beg&&ren==en)
return segt[root].val;
pushdown(root);
int mid=(rst+ren)/2;
if (en<=mid)
return query(root*2,rst,mid,beg,en);
else if (beg>=mid+1)
return query(root*2+1,mid+1,ren,beg,en);
else
return min(query(root*2,rst,mid,beg,mid),query(root*2+1,mid+1,ren,mid+1,en));//改这里
}
int main()
{
memset(segt,0,sizeof(segt));
for(int k=1;k<=10;k++)
scanf("%d",&a[k]);
build(1,1,10);
int i,j,val;
// cin>>i>>j>>val;
// update(1,1,10,i,j,val);
while(scanf("%d %d",&i,&j))
{
cout<<query(1,1,10,i,j)<<endl;
}
return 0;
}
对于第i个区间li,ri至少要取ki个点,要求至少要取多少个点
这个题目就是贪心,将所有区间按右端点从小到大排序
然后对于每个区间从右往左取,直到满足要求
很好的题目,现在放上ac代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define maxn 505000
#define inf 1000000
using namespace std;
class segtree
{
public:
int val,addmark;
};
segtree segt[maxn<<2];
void pushdown(int root)
{
if (segt[root].addmark!=0)
{
segt[root*2].val+=segt[root].addmark;
segt[root*2].addmark+=segt[root].addmark;
segt[root*2+1].val+=segt[root].addmark;
segt[root*2+1].addmark+=segt[root].addmark;
segt[root].addmark=0;
}
return;
}
void update(int root,int rst,int ren,int beg,int en,int val)
{
if (rst>=beg&&ren<=en)
{
segt[root].val+=val;
segt[root].addmark+=val;
}
else if (rst>en||ren<beg) {return;}
else
{
pushdown(root);
int mid=(rst+ren)/2;
update(root*2,rst,mid,beg,en,val);
update(root*2+1,mid+1,ren,beg,en,val);
segt[root].val=segt[root*2].val+segt[root*2+1].val;
}
}
int query(int root,int rst,int ren,int beg,int en)
{
if (rst>en||ren<beg)
return 0;
if (rst==beg&&ren==en)
return segt[root].val;
pushdown(root);
int mid=(rst+ren)/2;
if (en<=mid)
return query(root*2,rst,mid,beg,en);
else if (beg>=mid+1)
return query(root*2+1,mid+1,ren,beg,en);
else
return query(root*2,rst,mid,beg,mid)+query(root*2+1,mid+1,ren,mid+1,en);
}
struct Data
{
int l,r,k;
};
Data a[1001000];
bool cmp(Data aa,Data bb)
{
return aa.r<bb.r;
}
int vis[maxn];
int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
for (int k=1;k<=m;k++)
scanf("%d %d %d",&a[k].l,&a[k].r,&a[k].k);
sort(a+1,a+1+m,cmp);
memset(segt,0,sizeof(segt));
memset(vis,0,sizeof(vis));
for (int k=1;k<=m;k++)
{
int save=query(1,1,n,a[k].l,a[k].r);
int poi=a[k].r;
while(save<a[k].k)
{
while(vis[poi])
poi--;
update(1,1,n,poi,poi,1);
vis[poi]=1;
save++;
}
}
printf("%d\n",query(1,1,n,1,n));
}
return 0;
}