HDU 4902

数据太弱,直接让我小暴力一下就过了,一开始没注意到时间是15000MS,队友发现真是太给力了

#include <cstdio>
#include <cstring>
int n,q,a[100005],x[100005],p,l[100005],r[100005],t[100005];
int tree[1000005];
void build(int l, int r, int rt)
{
    tree[rt]=-1;
    if(l==r){
        tree[rt]=0;
        return;
    }
    int m=(l+r)/2;
    build(l,m,rt*2);
    build(m+1,r,rt*2+1);
}
void update(int x, int y, int z, int l, int r, int rt)
{
    if(x<=l&&y>=r){
        tree[rt]=z;
        return;
    }
    if(tree[rt]!=-1) {
        tree[rt*2]=tree[rt];
        tree[rt*2+1]=tree[rt];
        tree[rt]=-1;
    }
    int m=(l+r)/2;
    if(x<=m) update(x,y,z,l,m,rt*2);
    if(y>m) update(x,y,z,m+1,r,rt*2+1);
}
int query(int k, int l, int r, int rt)
{
    if(tree[rt]!=-1) return tree[rt];
    int m=(l+r)/2;
    if(k<=m) return(query(k,l,m,rt*2));
    else return(query(k,m+1,r,rt*2+1));
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--){
        memset(tree,-1,sizeof(tree));
        scanf("%d",&n);
        build(1,n,1);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        scanf("%d",&q);
        for(int i=1; i<=q; i++)
        {
            scanf("%d%d%d%d",&t[i],&l[i],&r[i],&x[i]);
            if(t[i]==1) update(l[i],r[i],i,1,n,1);
        }
        for(int i=1; i<=n; i++){
            p=query(i,1,n,1);
            if(p) a[i]=x[p];
            for(int j=p+1; j<=q; j++)
            if(t[j]==2&&l[j]<=i&&r[j]>=i){
                if(a[i]>x[j]){
                    int aa=a[i],bb=x[j],t=aa%bb;
                    while(t!=0){
                        aa=bb;
                        bb=t;
                        t=aa%bb;
                    }
                    a[i]=bb;
                }
            }
        }
        for(int i=1; i<=n; i++)
            printf("%d ",a[i]);
        printf("\n");
    }
}

CLJ给出的正确题解:

  

既然gcd(a[i],x)<0.5a[i]

  那么最多每个数字修改不会超过32次,

应该便是储存区间最大值以及增加判断区间内数字是否一致的flag

  每次对于区间最大值>x的区间进行修改,最差情况无非是每个数字都不同,且数字都大于x,nlgn,而最多就修改32次,因此最差情况nlg^2n。

  虽然证明麻烦,但是凭借感觉还是能够明白的。

实现相对简单便不再累赘。

HDU 4902,布布扣,bubuko.com

时间: 2024-10-18 06:22:43

HDU 4902的相关文章

HDU 4902 Nice boat(线段树)

HDU Nice boat 题目链接 题意:给定一个序列,两种操作,把一段变成x,把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 思路:线段树,每个结点多一个cover表示该位置以下区间是否数字全相同,然后每次延迟操作,最后输出的时候单点查询即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 1

HDU 4902 (线段树)

Problem Nice boat(HDU 4902) 题目大意 维护一个序列,两种操作. 第一种操作,将一段区间[l,r]赋值为x. 第二种操作,将一段区间[l,r]中大于等于x的数与x求gcd. 询问所有操作结束后的序列. 解题分析 用线段树开一个标记same,表示这段区间中的数是否相同,若相同则为该数,否则为-1. 对于第二种操作,对于覆盖区间内的same不为-1的子区间暴力修改. 虽然时限有15s,但貌似跑得挺快的,只用了1s,不知是数据水还是什么缘故. 参考程序 1 #include

HDU 4902 Matrix multiplication

点击打开链接 Matrix multiplication Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 2113    Accepted Submission(s): 956 Problem Description Given two matrices A and B of size n×n, find the product o

HDU 4902 Nice boat(线段树 区间更新)

Nice boat 大意:给你一个区间,每次可以进行两种操作,1:把区间中的数全都变成x  2:把区间中大于x的数变成gcd(a[i], x),最后输出序列. 思路:线段树成段更行,用num数组的叶子存储数据,节点当作lazy来使用. 1 #include <stdio.h> 2 const int maxn = 100005; 3 4 int num[maxn<<2]; 5 6 int gcd(int a, int b){ 7 return b?gcd(b, a%b):a; 8

HDU 4902 线段树(区间更新)

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 353    Accepted Submission(s): 169 Problem Description There is an old country and the king fell in love with a devil. The devil alw

HDU 4902 (牛叉的线段树)

Nice boat Problem Description There 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 c

HDU 4902 线段树||暴力

给定一个序列,两种操作 1:把一段变成x. 2:把一段每个数字,如果他大于x,就变成他和x的gcd,求变换完后,最后的序列. 线段树解法:用lazy标记下即可,优化方法还是很巧妙的, Accepted 4902 515MS 3308K 1941 B C++ #include "stdio.h" #include "string.h" struct node { int l,r,x;// 在叶子节点代表值,树节点代表成端更新的lazy操作. }data[400010]

HDU - 4902 Nice boat

Description There 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 re

HDU 4902 Nice boat 多校4 线段树

给定n个数 第一个操作和普通,区间覆盖性的,把l-r区间的所有值改成固定的val 第二个操作是重点,输入l r x 把l-r区间的所有大于x的数,变成gcd(a[i],x) a[i]即指满足条件的序列上的数值 最后才输出所有值 当时苦思这个地方如何优化,想着不可能单点去更新吧,但是区间gcd,不能保存下来,一来他是要>x才有效,本来聪哥想了一种先把各种x gcd一遍,最后在push下去,发现不行,就是因为他对>x才有效,你在区间就直接gcd了,那不是把不该gcd的也给搞了 还想过说先存起来所有