多校第4场 HDU 4902 Nice boat 线段树

思路:这题比赛的时候宝哥说的思路我觉得对的,就是当是2操作的时候,先把数放到数组里,最后查询输出的时候再统一计算,不过那时敲得烂死了,debug了两天,靠……

上午写的vector在pushDown的时候又忘了clear了,然后MLE了一早上,尼玛,还以为用的数组太大超了,然后又改成结构体,还是MLE,最后把别人的代码交上去发现没MLE,疯了一中午,最后无聊的时候才发现这个错误,尼玛……发现自己调试怎么变得这么弱了呢……

还有一个需要注意的问题是1与2操作的处理上比较容易出错,这也是我WA了一下午的原因……唉……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define INF 510010
#define maxn 400010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int key[maxn];
short lazy[maxn];
vector<int>ve[maxn];
int n,m;
int gcd(int a,int b)
{
    return !b?a:gcd(b,a%b);
}
void pushdown(int i,int l,int r)
{
    if(l==r) return ;
    if(lazy[i]==1)
    {
        key[i<<1]=key[i<<1|1]=key[i];
        lazy[i<<1]=lazy[i<<1|1]=lazy[i];
        ve[i<<1]=ve[i<<1|1]=ve[i];
        lazy[i]=0;
    }
    else
    {
        for(int j=0; j<ve[i].size(); j++)
        {
            ve[i<<1].push_back(ve[i][j]);
            ve[i<<1|1].push_back(ve[i][j]);
        }
    }
    ve[i].clear();
}
void update(int i,int l,int r,int L,int R,int v,int c)
{
    pushdown(i,l,r);
    if(L==l&&r==R)
    {
        if(c==1) lazy[i]=1,key[i]=v,ve[i].clear();
        else ve[i].push_back(v);
        return ;
    }
    int mid=(l+r)>>1;
    if(R<=mid) update(lson,L,R,v,c);
    else if(L>mid) update(rson,L,R,v,c);
    else
    {
        update(lson,L,mid,v,c);
        update(rson,mid+1,R,v,c);
    }
}
void query(int i,int l,int r)
{
    pushdown(i,l,r);
    if(l==r)
    {
        for(int j=0; j<ve[i].size(); j++)
        {
            if(key[i]>ve[i][j])
                key[i]=gcd(key[i],ve[i][j]);
            if(key[i]==1) break;
        }
        printf("%d ",key[i]);
        return ;
    }
    int mid=(l+r)>>1;
    query(lson);
    query(rson);
}
void build(int i,int l,int r)
{
    key[i]=lazy[i]=0;
    ve[i].clear();
    if(l==r)
    {
        scanf("%d",&key[i]);
        return ;
    }
    int mid=(l+r)>>1;
    build(lson);
    build(rson);
}
void debug(int i,int l,int r )
{
    printf("结点:%3d 范围:%3d~~%3d 传值:%11d 标记:%3d\n",i,l,r,key[i],lazy[i]);
    if(l==r) return ;
    int mid=(l+r)>>1;
    debug(lson);
    debug(rson);
}
int main()
{
    //freopen("test.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        int i;
        scanf("%d",&n);
        build(1,1,n);
        scanf("%d",&m);
        while(m--)
        {
            int c,l,r,x;
            scanf("%d%d%d%d",&c,&l,&r,&x);
            update(1,1,n,l,r,x,c);
            //debug(1,1,n);
            //puts("");
        }
        query(1,1,n);
        puts("");
    }
    return 0;
}

多校第4场 HDU 4902 Nice boat 线段树

时间: 2024-08-06 15:51:45

多校第4场 HDU 4902 Nice boat 线段树的相关文章

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

2017多校第8场 HDU 6133 Army Formations 线段树合并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6133 题意:给你一棵n个节点的二叉树,每个节点有一个提交任务的时间,每个节点总的提交任务的罚时为:提交这个节点和其子树所有的任务,每个任务提交时间的总和为该点的罚时.求每个节点提交完所有任务的最小罚时. 解法:根据题意,我们可以知道每个节点的提交的最小罚时为,按照任务的提交时间从小到大的来提交任务,可以得到最小的罚时.所以我们可以用线段树合并,先建立权值线段树,记录权值区间L到R的所有权值sum与s

HDU 4902 Nice boat 线段树+离线

据说暴力也过了.还傻逼地写了这么长. . . #include <stdio.h> #include <string.h> #include <math.h> #include <iostream> using namespace std; #define ll long long #define L(x) (x<<1) #define R(x) (x<<1|1) #define Val(x) tree[x].val #define

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

题意:给一个数字序列,第一类操作是将[l,r]内的数全赋为x ,第二类操作是将[l,r]中大于x的数赋为该数与x的gcd,若干操作后输出整个序列. 解法: 本题线段树要维护的最重要的东西就是一个区间内所有数是否相等的标记.只维护这个东西都可以做出来. 我当时想歪了,想到维护Max[rt]表示该段的最大值,最大值如果<=x的话就不用更新了,但是好像加了这个“优化”跑的更慢了. 我想大概是因为如果两个子树最大值或者整个两个子树的数不完全相等的话,根本不能直接下传这个值或者下传gcd,因为你不知道要更

hdoj 4901 The Romantic Hero DP hdoj 4902 Nice boat 线段树

惨遭丽洁乱虐..这一场也是比得乱七八糟的,4902本是丽洁定义比较难的题,结果数据随机的,被许多暴力水过了..4905考察的是四边形不等式优化,但是这道题的dp方程实际上不满足该优化的条件..朴素的o(n^3)会超时,所以这题目前是没有正解了..我还写了个这题的贪心,强度挺高,可以对大概一半数据,错的误差也只有个位数,还揪出官方第五个数据..朴素dp和贪心跑这个数据都比官方数据多了1,也就证明这题不满足四边形不等式优化的条件.. http://acm.hdu.edu.cn/showproblem

第四场 hdu 6070 Dirt Ratio (线段树+二分)

http://acm.hdu.edu.cn/showproblem.php?pid=6070 题目大意:给出的序列上的数代表颜色,求子序列中不同数字的个数X与子序列长度Y中,X/Y的最小值 解题思路:思路和官方给的想法一样 值得注意的是线段树的节点中储存的是 size(l,r)+mid×l ,在建树时 mid×l 作为树节点的初始值,然后不断更新当前颜色对于 前一个相同颜色的位置+1 到 当前位置 的节点值+1,然后询问 1 到 当前位置的最小值 是否小于mid*(i+1). 虽然最后要打印小数

HDU-DuoXiao第二场hdu 6315 Naive Operations 线段树

hdu 6315 题意:对于一个数列a,初始为0,每个a[ i ]对应一个b[i],只有在这个数字上加了b[i]次后,a[i]才会+1. 有q次操作,一种是个区间加1,一种是查询a的区间和. 思路:线段树,一开始没用lazy,TLE了,然后开始想lazy的标记,这棵线段树的特点是,每个节点维护 :一个区间某个a 要增加1所需个数的最小值,一个区间已加上的mx的最大值标记,还有就是区间和sum. (自己一开始没有想到mx标记,一度想把lazy传回去. (思路差一点就多开节点标记. #include

hdu 5316 Magician(2015多校第三场第1题)线段树单点更新+区间合并

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5316 题意:给你n个点,m个操作,每次操作有3个整数t,a,b,t表示操作类型,当t=1时讲a点的值改成b:当t=0时,查询区间a,b之间最大的子序列和,这个子序列中的相邻的元素的原来的下标奇偶性都不同. 思路:这道题难点就在查询,其余都是模板,而根据查询,你只要分别把下一个区间的奇偶最大的情况分别比较,合并到上一个区间这样可以构建一个每个节点存有区间中奇开头偶开头,奇结尾,偶结尾这些区间情况的树.

hdu 4902 Nice boat(2014多校训练第4场 1006)

Nice boat                                                                           Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description There is an old country and the king fell in love with a d