hdoj 4902 Nice boat【线段树成段更新】

题目:hdoj 4902 Nice boat 


来源:2014 Multi-University Training Contest 4


题意:给出n个数,有两种操作,第一种是给l--r区间全部替换为x,第二种操作是给 l---r 区间上比x大的替换为gcd(x,num),求最后区间的值。


分析:很明显的线段是入门题目,当然定位也是签到题,刚学了线段树,没写过,比赛的时候把一个地方写错了。导致一直wa、、、

这个题目第一种操作直接更新到一段区间上x,第二种操作同样也更新到区间上,注意往下找的时候一定要更新一次。


代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <list>
using namespace std;
#define Del(a,b) memset(a,b,sizeof(a))
const long long N = 110000;
long long a[N];
long long gcd(long long x,long long y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
struct Node
{
    long long l,r;
    long long x;
};
Node tree[N*5];
void build(long long l,long long r,long long v)
{
    tree[v].l=l;
    tree[v].r=r;
    if(l==r)
    {
        tree[v].x=a[l];
        return ;
    }
    long long mid=(l+r)>>1;
    build(l,mid,v*2);
    build(mid+1,r,v*2+1);
}
void push_down(int o)  //向下更新
{
    tree[o+o].x=tree[o+o+1].x=tree[o].x;
    tree[o].x=0;  //注意这里写法
}
void update(long long l,long long r,long long val,long long o)
{
    if(tree[o].l==l&&tree[o].r==r)
    {
        tree[o].x=val;
        return ;
    }
    if(tree[o].x>0)
        push_down(o);
    long long mid=(tree[o].l+tree[o].r)>>1;
    if(r<=mid)
        update(l,r,val,o+o);
    else if(l>mid)
        update(l,r,val,o+o+1);
    else
    {
        update(l,mid,val,o*2);
        update(mid+1,r,val,o*2+1);
    }
}
void query(long long l,long long r,long long val,long long o)
{
    if(tree[o].l==l && tree[o].r==r && tree[o].x!=0)
    {
        if(tree[o].x>val)
            tree[o].x=gcd(tree[o].x,val);
        return ;
    }
    if(tree[o].x>0)
        push_down(o);
    long long mid=(tree[o].l+tree[o].r)>>1;
    if(r<=mid)
        query(l,r,val,o+o);
    else if(l>mid)
        query(l,r,val,o+o+1);
    else
    {
        query(l,mid,val,o*2);
        query(mid+1,r,val,o*2+1);
    }
}
void get_ans(long long l,long long r,long long o)
{
    if(tree[o].l==tree[o].r)
    {
        a[l]=tree[o].x;
        return ;
    }
    if(tree[o].x>0)
        push_down(o);
    long long mid=(tree[o].l+tree[o].r)>>1;
    if(r<=mid)
        get_ans(l,r,o+o);
    else if(l>mid)
        get_ans(l,r,o+o+1);
    else
    {
        get_ans(l,mid,o*2);
        get_ans(mid+1,r,o*2+1);
    }
}
int main()
{
    //freopen("Input.txt","r",stdin);
    long long T;
    scanf("%I64d",&T);
    while(T--)
    {
        Del(tree,0);
        long long n;
        scanf("%I64d",&n);
        for(int i=1; i<=n; i++)
            scanf("%I64d",&a[i]);
        build(1,n,1);
        long long m;
        scanf("%I64d",&m);
        while(m--)
        {
            long long x,y,z,val;
            scanf("%I64d%I64d%I64d%I64d",&x,&y,&z,&val);
            if(x==1)
                update(y,z,val,1);
            else if(x==2)
                query(y,z,val,1);
        }
        get_ans(1,n,1);
        for(int i=1; i<=n; i++)
            printf("%I64d ",a[i]);
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(Algorithm,算法,namespace,线段树,迭代器)