线段树模板
来源:互联网 发布:淘宝api 获取订单信息 编辑:程序博客网 时间:2024/06/16 20:44
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define maxn 1000#define inf 1000000using 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 1000000using 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;}
阅读全文
0 0
- ACM 线段树模板(模板)
- 线段树模板
- hdu_1166_线段树模板
- 线段树模板
- 线段树模板 poj2777
- 线段树模板
- 线段树模板
- 线段树-模板
- 线段树模板
- 线段树模板
- 线段树模板
- Hdu1166-- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- yii2 DatePicker时间选择器的使用(例:选择到年)
- [状压DP] HDU 5823 Color II
- LightOJ
- oracle数据库emp表 及其关联的表
- myeclipse 搭建最简单的Rest 服务
- 线段树模板
- UVALive
- 深拷贝和浅拷贝
- 割点
- socket 多线程http服务器
- ACdream 1073 雷霆战机 (模拟 + set容器的使用)
- AngularJs+用户信息表基本功能实现
- C++中vector容器的基本用法总结
- jsp模拟留言板