线段树模板

来源:互联网 发布:淘宝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;}

最近做了到题目,就是给m个区间
对于第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;}



原创粉丝点击