线段树专题(二)

  • Post author:
  • Post category:其他


马不停蹄,马不停蹄,才写完上一部分,没有时间休息,又要开始下一部分了。这部分主要是线段树区间更新的难题和区间合并的一些题目,最后最困难的扫描线算法应该会出现在第三部分。



第一题

ZOJ 1610

分析:首先声明一点这道题我没有AC,当然不是因为我不会,而是因为坑人的ZOJ又爆炸了,交不了代码。所以万一我的代码出了问题,你们不准打我,思路是肯定没有问题的。

其实这道题不算难题啦,只是因为我的失误,错把它分到第二部分了,唉,就当热身。

给你N个气球,在区间端上刷颜色,最后让你求每个颜色的段数。那么还是老套路,区间更新+最后查询一次。

#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
#define   maxn          8000+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10

typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;

const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;

inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}

//--------------------------------------------------

int col[maxn<<2];
int vis[maxn];
int anw[maxn];
void build(int l,int r,int rt){
    col[rt]=-1;
    if(l==r){
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
}
void pushdown(int rt){
    if(col[rt]!=-1){
        col[rt<<1]=col[rt<<1|1]=col[rt];
        col[rt]=-1;
    }
}
void update(int l,int r,int rt,int L,int R,int p){
    if(L<=l&&r<=R){
        col[rt]=p;
        return;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    if(L<=m)update(lson,L,R,p);
    if(R>m) update(rson,L,R,p);
}
void query(int l,int r,int rt){
    if(col[rt]!=-1){
        for(int i=l;i<=r;i++)
            anw[i]=col[rt];
        return ;
    }
    if(l==r){
        anw[l]=-1;
        return ;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    query(lson);
    query(rson);
}
int main(){
    //freopen("d:\\acm\\in.in","r",stdin);
    int n;
    while(~scanf("%d",&n)){
        build(1,8000,1);
        while(n--){
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            a++;
            update(1,8000,1,a,b,c);
        }
        query(1,8000,1);
        clr(vis,0);
        if(anw[1]!=-1)vis[anw[1]]++;
        for(int i=2;i<=8000;i++)
            if(anw[i]!=-1&&anw[i]!=anw[i-1])
                vis[anw[i]]++;
        for(int i=0;i<=8000;i++)
            if(vis[i])
                printf("%d %d\n",i,vis[i]);
        puts("");
    }
    return 0;
}


第二题

POJ 3264

分析:第二题也不难。是求区间最大值与最小值的差+区间更新。

#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
#define   maxn          50000+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10

typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;

const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;

inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}

//--------------------------------------------------

int minn[maxn<<2];
int maxx[maxn<<2];
void pushup(int rt){
    minn[rt]=min(minn[rt<<1],minn[rt<<1



版权声明:本文为shengtao96原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。