線段樹小結

今天練了一天的線段樹的(水)題,在此做一些總結.
A hdu1754 I Hate It
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=1754
單點更新+區間查詢

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int n,m,a,b;
int sum[800005];
char t; 
void pushup(int rt)
{
    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int rt,int l,int r)
{
    if(l==r)
    {
        scanf("%d",&sum[rt]);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt); 
}
void update(int rt,int l,int r,int q,int x)
{
    if (l==r)
    {
        sum[rt]=x;
        return;
    }
    int mid=(l+r)>>1;
    if (q<=mid)update(lson,q,x);
    else update(rson,q,x);
    pushup(rt);
}
int query(int rt,int l,int r,int x,int y)
{
    if (l>=x&&r<=y)
    {
        return sum[rt];
    }
    int mid=(l+r)>>1;
    int ans=0;
    if (x<=mid)ans=max(ans,query(lson,x,y));
    if (y>mid)ans=max(ans,query(rson,x,y));
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&m)) 
    { 
        build(1,1,n); 
        getchar(); 
        for (int i=1;i<=m;i++)
        {
            scanf("%c%d%d",&t,&a,&b);
            if (t=='U') {update(1,1,n,a,b);}
            if (t=='Q') {printf("%d\n",query(1,1,n,a,b));}
            getchar(); 
        }
    } 
    return 0;
}

B HDU 1394 Minimum Inversion Number
傳送門http://acm.hdu.edu.cn/showproblem.php?pid=1394
線段樹求逆序對(暴力或歸併排序均可)

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int sum[20005],n,a[5005],x; 
void pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1]; 
} 
void build(int rt,int l,int r)
{
    if (l==r)
    { 
        sum[rt]=0;
        return; 
    } 
    int mid=(l+r)>>1;
    build(lson);
    build(rson); 
    pushup(rt); 
} 
int query(int rt,int l,int r,int x,int y)
{
     if (l>=x&&r<=y)
     {
        return sum[rt]; 
     } 
     int mid=(l+r)>>1;
     int ans=0; 
     if (x<=mid) ans+=query(lson,x,y);
     if (y>=mid) ans+=query(rson,x,y);
     return ans;  
} 
void update(int rt,int l,int r,int x)
{
    if (l==r) 
    {
        sum[rt]++;
        return; 
    } 
    int mid=(l+r)>>1;
    if (x<=mid) update(lson,x);
    else update(rson,x);  
    pushup(rt); 
} 
int main()
{
    while(~scanf("%d",&n))
    {  
        build(1,1,n); 
        x=0; 
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            x+=query(1,1,n,a[i]+1,n);
            update(1,1,n,a[i]+1); 
        } 
        int ans=x;
        for (int i=1;i<=n;i++)
        {
            x+=n-a[i]-a[i]-1;
            ans=min(ans,x); 
        } 
        printf("%d\n",ans); 
    } 
}

C HDU 2795 Billboard
傳送門:http://acm.hdu.edu.cn/showproblem.php?pid=2795

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int sum[800005],h,w,n,x;
void pushup(int rt)
{
    sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
}
void build(int rt,int l,int r)
{
    if (l==r)
    {
        sum[rt]=w;
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
int query(int rt,int l,int r,int x)
{
    int ret;
    if (l==r)
    {
        sum[rt]-=x;
        return l;
    }
    int mid=(l+r)>>1;
    if (x<=sum[rt<<1]) ret=query(lson,x);
    else ret=query(rson,x);
    pushup(rt);
    return ret;
}
int main()
{
    while (~scanf("%d%d%d",&h,&w,&n))
    {
        int z=min(h,n);
        build(1,1,z);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if (sum[1]<x) printf("-1\n");
            else printf("%d\n",query(1,1,z,x));
        }
    } 
}

D POJ 3468 A Simple Problem with Integers
傳送門:http://poj.org/problem?id=3468
區間更新+查詢

#include<cstdio>
#define lson u<<1,l,mid
#define rson u<<1|1,mid+1,r
#define maxn 200005
#define ll long long
struct node{
    int l,r;
    ll s;
    ll add;
}nod[4*maxn];
int n,m;
void pushup(int u)
{
    nod[u].s=nod[u<<1].s+nod[u<<1|1].s; 
}
void build(int u,int l,int r)
{
    nod[u].l=l;nod[u].r=r;
    nod[u].add=0;
    if(l==r)
    {
        scanf("%lld",&nod[u].s);
        return;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(u);
}
void pushdown(int u)
{
    nod[u<<1].add+=nod[u].add;
    nod[u<<1|1].add+=nod[u].add;
    nod[u<<1].s+=(nod[u<<1].r-nod[u<<1].l+1)*nod[u].add;
    nod[u<<1|1].s+=(nod[u<<1|1].r-nod[u<<1|1].l+1)*nod[u].add;
    nod[u].add=0;
}
void update(int u,int l,int r,int x,int y,ll add)
{
    if(l==x&&r==y) 
    {
        nod[u].s+=(r-l+1)*add;
        nod[u].add+=add;
        return;
    }
    if(nod[u].add) pushdown(u);
    int mid=(l+r)>>1;
    if(y<=mid) update(lson,x,y,add);
    else if(x>mid) update(rson,x,y,add);
    else 
    {
        update(lson,x,mid,add);
        update(rson,mid+1,y,add);
    }
    pushup(u);

}
ll query(int u,int l,int r,int x,int y)
{
    if(x==l&&y==r) return nod[u].s;
    if(nod[u].add) pushdown(u);
    int mid=(l+r)>>1;
    if(y<=mid) return query(lson,x,y);
    else if(x>mid) return query(rson,x,y);
    else
    {
        ll ans=0;
        ans+=query(lson,x,mid);
        ans+=query(rson,mid+1,y);
        return ans;
    }

}
int main()
{
    int x,y;
    char k;
    ll z;
    while (~scanf("%d%d",&n,&m))
    {
        build(1,1,n);
        for(int i=1;i<=m;i++ )
        {
            getchar();
            scanf("%c",&k);
            if(k=='C') 
            {
                scanf("%d%d%lld",&x,&y,&z);
                update(1,1,n,x,y,z);
            }
            else if(k=='Q') 
            {
                scanf("%d%d",&x,&y);
                printf("%lld\n",query(1,1,n,x,y));
            }
        }
    }
    return 0;
}

E POJ 2528 Mayor’s posters
傳送門:http://poj.org/problem?id=2528
基礎離散化

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
int t,n,sum[200005],ans,hash[10000005],l[10005],r[10005],a[20010],lazy[200005],f[20005];
void pushdown(int rt)
{
    if (lazy[rt]!=0&&sum[rt]!=-1)
    {
        lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
        lazy[rt]=0;
        sum[rt<<1]=sum[rt<<1|1]=sum[rt];
    }

}
void pushup(int rt)
{
    if (sum[rt<<1]==sum[rt<<1|1]) sum[rt]=sum[rt<<1];
    else sum[rt]=-1;
}
void update(int rt,int l,int r,int x,int y,int add)
{
    if (l>=x&&r<=y)
    {       
        sum[rt]=add;
        lazy[rt]=add;
        pushdown(rt);
        return;
    }
    pushdown(rt);
    int mid=(l+r)>>1;
    if (x<=mid) update(lson,x,y,add);
    if (y>mid) update(rson,x,y,add);
    pushup(rt);
}
void query(int rt,int l,int r)
{
    if (sum[rt]!=-1)
    {
        if (f[sum[rt]]!=1)
        {
            f[sum[rt]]=1;
            ans++;
        }
        return;
    }
    int mid=(l+r)>>1;
    query(lson);
    query(rson);
}
int main()
{
    scanf("%d",&t);
    while (t--)
    {
        memset(sum,0,sizeof(sum));
        memset(lazy,0,sizeof(lazy));
        memset(f,0,sizeof(f));
        scanf("%d",&n);
        for (int i=1;i<=n;i++)
        {
            scanf("%d%d",&l[i],&r[i]);
            a[i*2-1]=l[i];
            a[i*2]=r[i];
        }
        sort(a+1,a+1+n*2);
        int t=0;
        int pre=0;
        for (int i=1;i<=2*n;i++)
        {
            if (a[i]!=pre)
            {
                pre=a[i];
                t++;
                hash[a[i]]=t;
            }
        }
        for (int i=1;i<=n;i++)
        {
            update(1,1,t,hash[l[i]],hash[r[i]],i);
        }
        ans=0;
        query(1,1,t);
        printf("%d\n",ans);
    }
}

F http://blog.csdn.net/chen20000804/article/details/52046017
區間開方求和
G http://blog.csdn.net/chen20000804/article/details/51137428
包含了N種操作的題,現在終於可以1h內切了.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章