[HDU4902]Nice boat(线段树)

版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/CABI_ZGX/article/details/79976622

传送门
题意:
给你n个数,Q次操作,操作分两类
第一类操作(type1):将区间内[l,r]的数改成x
第二类操作(type2):将区间[l,r]a[i]>x的改成gcd(a[i],x)
你需要输出Q次操作后的序列


今天考试的第二题,还是比较良心的,结果考场上打多了一个else挂掉了(暴哭)

由于操作是区间全部修改,所以肯定有一段一段的是相同的。
考虑维护一个标记num:对于当前管理的一段区间数值是否全部相同,相同num=这个数值,不同num=-1,然后注意下放标记和上传标记即可。

还可以维护一个区间最大值mx,如果mx < x的话说明没有可以更新的,那么可以提速。

注意原题多组数据。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int gcd(int a,int b)
{
    if(b==0) return a;
    else return gcd(b,a%b);
}
struct trnode
{
    int l,r,lc,rc;
    int num;//区间内的数是否相同。
}tr[510000]; int trlen;
int a[510000];
void bt(int l,int r)
{
    trlen++;
    int now=trlen;
    tr[now].l=l;tr[now].r=r;tr[now].lc=tr[now].rc=-1;
    if(l==r) tr[now].num=a[l];
    if(l<r)
    {
        int mid=(l+r)/2;
        tr[now].lc=trlen+1;bt(l,mid);
        tr[now].rc=trlen+1;bt(mid+1,r);
        tr[now].num=(tr[tr[now].lc].num==tr[tr[now].rc].num)?tr[tr[now].lc].num:-1;
    }
}
void change1(int now,int L,int R,int x)
{
    if(L<=tr[now].l && tr[now].r<=R)
    {
        tr[now].num=x;
        return;
    }
    else
    {
        int l=tr[now].l,r=tr[now].r,lc=tr[now].lc,rc=tr[now].rc;
        int mid=(l+r)/2;
        if(tr[now].num>-1) tr[lc].num=tr[now].num,tr[rc].num=tr[now].num;
        if(R<=mid) change1(lc,L,R,x);
        else if(mid+1<=L) change1(rc,L,R,x);
        else
        {
            change1(lc,L,mid,x);
            change1(rc,mid+1,R,x);
        }
        tr[now].num=(tr[lc].num==tr[rc].num)?tr[lc].num:-1;
    }
}
void change2(int now,int L,int R,int x)
{
    if(L<=tr[now].l && tr[now].r<=R)
    {
        if(tr[now].num>-1)
        {
            if(tr[now].num>x) 
                tr[now].num=gcd(tr[now].num,x);
            return;
        }
    }
        int l=tr[now].l,r=tr[now].r,lc=tr[now].lc,rc=tr[now].rc;
        int mid=(l+r)/2;
        if(tr[now].num>-1) tr[lc].num=tr[now].num,tr[rc].num=tr[now].num;
        if(R<=mid) change2(lc,L,R,x);
        else if(mid+1<=L) change2(rc,L,R,x);
        else
        {
            change2(lc,L,mid,x);    
            change2(rc,mid+1,R,x);
        }
        tr[now].num=(tr[lc].num==tr[rc].num)?tr[lc].num:-1;
}
void print(int now,int l,int r)
{
    if(tr[now].num!=-1)
    {
        for(int i=tr[now].l;i<=tr[now].r;i++) printf("%d ",tr[now].num);
    }
    else
    {
        int lc=tr[now].lc,rc=tr[now].rc;
        if(tr[now].num>-1) tr[lc].num=tr[now].num,tr[rc].num=tr[now].num;
        int mid=(l+r)/2;
        print(tr[now].lc,l,mid);
        print(tr[now].rc,mid+1,r);
    }
}
int main()
{
//  freopen("b.in","r",stdin);
//  freopen("b.out","w",stdout);
    int T;scanf("%d",&T);
    while(T--)
    {
        int n,Q;scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        trlen=0; bt(1,n);
        scanf("%d",&Q);
        while(Q--)
        {
            int flag,l,r; int x;
            scanf("%d%d%d%d",&flag,&l,&r,&x);
            if(flag==1) change1(1,l,r,x);
            else change2(1,l,r,x);
        }
        print(1,1,n);
        printf("\n");
    }
    return 0;
}

Nice boat

08-03

Problem DescriptionnThere is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.nnLet us continue our story, z*p(actually you) defeat the 'MengMengDa' party's leader, and the 'MengMengDa' party dissolved. z*p becomes the most famous guy among the princess's knight party. nnOne day, the people in the party find that z*p has died. As what he has done in the past, people just say 'Oh, what a nice boat' and don't care about why he died.nnSince then, many people died but no one knows why and everyone is fine about that. Meanwhile, the devil sends her knight to challenge you with Algorithm contest.nnThere is a hard data structure problem in the contest:nnThere are n numbers a_1,a_2,...,a_n on a line, everytime you can change every number in a segment [l,r] into a number x(type 1), or change every number a_i in a segment [l,r] which is bigger than x to gcd(a_i,x) (type 2).nnYou should output the final sequence.n nnInputnThe first line contains an integer T, denoting the number of the test cases.nFor each test case, the first line contains a integers n.nThe next line contains n integers a_1,a_2,...,a_n separated by a single space.nThe next line contains an integer Q, denoting the number of the operations.nThe next Q line contains 4 integers t,l,r,x. t denotes the operation type.nnT<=2,n,Q<=100000na_i,x >=0na_i,x is in the range of int32(C++)n nnOutputnFor each test case, output a line with n integers separated by a single space representing the final sequence.nPlease output a single more space after end of the sequencen nnSample Inputn1n10n16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709 n10n1 3 6 74243042n2 4 8 16531729n1 3 4 1474833169n2 1 8 1131570933n2 7 9 1505795335n2 3 7 101929267n1 4 10 1624379149n2 2 8 2110010672n2 6 7 156091745n1 2 5 937186357n nnSample Outputn16807 937186357 937186357 937186357 937186357 1 1 1624379149 1624379149 1624379149

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试

关闭