• JDOJ 2175: 忠诚2


    JDOJ 2175: 忠诚2

    题目传送门

    Description

    老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。
    在询问过程中账本的内容可能会被修改

    Input

    输入中第一行有两个数m,n表示有m(m<=100000)笔账,n表示有n个问题,n<=100000。
    接下来每行为3个数字,第一个p为数字1或数字2,第二个数为x,第三个数为y
    当p=1 则查询x,y区间
    当p=2 则改变第x个数为y

    Output

    输出文件中为每个问题的答案。具体查看样例。

    Sample Input

    10 3 1 2 3 4 5 6 7 8 9 10 1 2 7 2 2 0 1 1 10

    Sample Output

    2 0

    题解:

    线段树。

    单点修改区间查询。

    模板。

    代码:

    #include<cstdio>
    #include<algorithm>
    #define lson pos<<1
    #define rson pos<<1|1
    using namespace std;
    int m,n;
    int a[100001];
    int tree[100001<<2];
    void build(int pos,int l,int r)
    {
        int mid=(l+r)>>1;
        if(l==r)
        {
            tree[pos]=a[l];
            return;
        }
        build(lson,l,mid);
        build(rson,mid+1,r);
        tree[pos]=min(tree[lson],tree[rson]);
    }
    void fix(int pos,int l,int r,int x,int y)
    {
        int mid=(l+r)>>1;
        if(l==r)
        {
            tree[pos]=y;
            return;
        }
        if(x<=mid)//attention
            fix(lson,l,mid,x,y);
        else if(x>mid)//attention
            fix(rson,mid+1,r,x,y);
        tree[pos]=min(tree[lson],tree[rson]);
    }
    int getsum(int pos,int l,int r,int x,int y)
    {
        int ret=1<<30;
        int mid=(l+r)>>1;
        if(x<=l && r<=y)
            return tree[pos];
        if(y<=mid)
            ret=min(ret,getsum(lson,l,mid,x,y));
        else if(x>mid)
            ret=min(ret,getsum(rson,mid+1,r,x,y));
        else
            ret=min(ret,min(getsum(lson,l,mid,x,y),getsum(rson,mid+1,r,x,y)));
        return ret;
    }
    int main()
    {
        int flag=1;
        scanf("%d%d",&m,&n);
        for(int i=1;i<=m;i++)
            scanf("%d",&a[i]);
        build(1,1,m);
        for(int i=1;i<=n;i++)
        {
            int p,a,b;
            scanf("%d",&p);
            if(p==1)
            {
                if(flag==1)
                {
                    scanf("%d%d",&a,&b);
                    printf("%d",getsum(1,1,m,a,b));
                    flag=0;
                }
                else
                {
                    scanf("%d%d",&a,&b);
                    printf(" %d",getsum(1,1,m,a,b));
                }
            }
            if(p==2)
            {
                scanf("%d%d",&a,&b);
                fix(1,1,m,a,b);
            }
        }
        return 0;
    }
    

    作为一个刚学线段树的蒟蒻,本人很负责地告诉大家:

    一定要注意二分递归的时候是<=还是< ,>=还是>。(代码中attention部分)

    否则就是:

    (这就是二分没学好的后果)

  • 相关阅读:
    存储过程
    C++学习总结
    Android快速开发系列 10个常用工具类
    SimpleHttpServer的学习之总体架构
    SimpleHttpServer的学习之UML
    SimpleHttpServer的学习(1)
    map用法
    idea 中resources下于java包名相同的包不能导入XML文件问题
    leetcode621
    Yukari's Birthday 枚举+二分 过程注意数据的溢出问题 HDU4430
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11302472.html
Copyright © 2020-2023  润新知