线段树单点更新

来源:互联网 发布:linux mkdir命令 编辑:程序博客网 时间:2024/05/23 02:06

hdu 1166 敌兵布阵

单点加减和区间求和

#include<stdio.h>#include<string.h>#define maxn 50005int sum[maxn<<2];void pushup(int rt){    sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(int l,int r,int rt){    if(l==r)    {        scanf("%d",&sum[rt]);        return;    }    int m=(l+r)>>1;    build(l,m,rt<<1);    build(m+1,r,rt<<1|1);    pushup(rt);}void update(int p,int add,int l,int r,int rt)  //单点加减{    if(l==r)    {        sum[rt]+=add;        return;    }    int m=(l+r)>>1;    if(p<=m)         update(p,add,l,m,rt<<1);    else         update(p,add,m+1,r,rt<<1|1);    pushup(rt);}int query(int z,int y,int l,int r,int rt)  //区间求和{    if(z<=l&&y>=r)    {        return sum[rt];    }    int v=0;    int m=(l+r)>>1;    if(z<=m)        v+=query(z,y,l,m,rt<<1);    if(y>m)        v+=query(z,y,m+1,r,rt<<1|1);    return v;}int main(){    int t,n,i,j;    scanf("%d",&t);    for(j=1;j<=t;j++)    {        printf("Case %d:\n",j);        scanf("%d",&n);        build(1,n,1);        char op[10];        while(scanf("%s",op))        {            if(op[0]=='E')                break;            int a,b;            scanf("%d %d",&a,&b);            if(op[0]=='Q')                 printf("%d\n",query(a , b , 1 , n , 1));            else if (op[0] == 'S')                 update(a , -b , 1 , n , 1);            else                 update(a , b , 1 , n , 1);        }    }    return 0;}
hdu 1754 I hate it

单点替换,区间最值

#include<stdio.h>#include<string.h>#define maxn 220005int sum[maxn<<2];int max(int a,int b){    return a>b?a:b;}void pushup(int rt){    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){    if(l==r)    {        scanf("%d",&sum[rt]);        return;    }    int m=(l+r)>>1;    build(l,m,rt<<1);    build(m+1,r,rt<<1|1);    sum[rt]=-1;    pushup(rt);}void update(int p,int add,int l,int r,int rt){    if(l==r)    {        sum[rt]=add;        return;    }    int m=(l+r)>>1;    if(p<=m)         update(p,add,l,m,rt<<1);    else         update(p,add,m+1,r,rt<<1|1);    pushup(rt);}int query(int z,int y,int l,int r,int rt){    if(z<=l&&y>=r)    {        return sum[rt];    }    int v=-1;    int m=(l+r)>>1;    if(z<=m)        v=max(v,query(z,y,l,m,rt<<1));    if(y>m)        v=max(v,query(z,y,m+1,r,rt<<1|1));    return v;}int main(){    int t,n,i,j,m;    while (~scanf("%d%d",&n,&m))    {        build(1,n,1);        char op[2];        while(m--)        {            int a,b;            //scanf("%c",&op);            //scanf("%d %d",&a,&b);            scanf("%s%d%d",op,&a,&b);            if(op[0]=='Q')                 printf("%d\n",query(a , b , 1 , n , 1));            else                 update(a , b , 1 , n , 1);        }    }    return 0;}
hdu 1394 Minimum Inversion Number

线段树求出最初逆序数,再按性质一次算出每次的结果

单点增减,区间求和,已经算过的数值赋成1,每次查询(x[i],n-1)区间的值

#include<stdio.h>#include<string.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 5005int sum[maxn<<2],n;int min(int a,int b){    return a<b?a:b;}void pushUp(int rt){    sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void build(){    int i;    for(i=0;i<=n*4;i++)        sum[i]=0;    //memset(sum,0,sizeof(sum));}void update(int p,int l,int r,int rt){    if(l==r)    {        sum[rt]++;        return;    }    int m=(l+r)>>1;    if(p<=m)        update(p,lson);    else        update(p,rson);    pushUp(rt);}int query(int z,int y,int l,int r,int rt){    if(z<=l&&r<=y)    {        return sum[rt];    }    int m=(l+r)>>1;    int v=0;    if(z<=m)        v+=query(z,y,lson);    if(y>m)        v+=query(z,y,rson);    return v;}int main(){    int i,num[maxn],ni,h;    while(~scanf("%d",&n))    {        ni=0;        build();        for(i=0;i<n;i++)        {            scanf("%d",&num[i]);            ni+=query(num[i],n-1,0,n-1,1);            update(num[i],0,n-1,1);        }        h=ni;        for(i=0;i<n;i++)        {            //ni+=-(num[i])+(n-num[i]-1);            ni+=n-num[i]-num[i]-1;            h=min(h,ni);        }        printf("%d\n",h);    }    return 0;}
hdu 2759Billboard

高h宽w的广告牌,向上面贴高均为1广告(宽度不定),求能贴上的最高行

#include<stdio.h>#include<string.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 200010int d(int a,int b){    return a>b?a:b;}int max[maxn<<2];int h,w,n;void build(int l,int r,int rt){    max[rt]=w;    if(l==r)        return;    int m=(l+r)>>1;    build(lson);    build(rson);}void pushUp(int rt){    max[rt]=d(max[rt<<1],max[rt<<1|1]);}int query(int x,int l,int r,int rt){    if(l==r)    {        max[rt]-=x;        return l;    }    int m=(l+r)>>1;    int v=(max[rt<<1]>=x)?query(x,lson):query(x,rson);    pushUp(rt);    return v;}int main(){    int i,j,k,l,m;    while(~scanf("%d %d %d",&h,&w,&n))    {        int t;        if(h>n)            h=n;        build(1,h,1);        for(i=0;i<n;i++)        {            scanf("%d",&t);            if(max[1]<t)                printf("%d\n",-1);            else                printf("%d\n",query(t,1,h,1));        }    }    return 0;}





原创粉丝点击