• 洛谷 P816 忠诚 题解


    每日一题 day28 打卡

    Analysis

    这道题用线段树维护区间最小值很简单,因为没有修改所以连lazy_tag都不用,但是这道题可以用树状数组维护区间最小值,非常骚气。

    线段树代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define int long long
     7 #define maxn 1000000+10
     8 using namespace std;
     9 inline int read() 
    10 {
    11     int x=0;
    12     bool f=1;
    13     char c=getchar();
    14     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
    15     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    16     if(f) return x;
    17     return 0-x;
    18 }
    19 inline void write(int x)
    20 {
    21     if(x<0){putchar('-');x=-x;}
    22     if(x>9)write(x/10);
    23     putchar(x%10+'0');
    24 }
    25 int m,n;
    26 int a[maxn];
    27 struct Segment_tree
    28 {
    29     struct Segment_tree_node
    30     {
    31         int l,r,val;
    32     }node[maxn*4];
    33     int n;
    34     inline int size() {return n;} 
    35     inline int left_s(int x) {return (x<<1);}
    36     inline int right_s(int x) {return ((x<<1)|1);}
    37     inline void init(int l,int r)
    38     {
    39         n=r-l+1;
    40         node[1].l=1;
    41         node[1].r=n;
    42         build(1);
    43     }
    44     inline void push_up(int x)
    45     {
    46         node[x].val=min(node[left_s(x)].val,node[right_s(x)].val);
    47     }
    48     inline void build(int x)
    49     {
    50         if(node[x].l==node[x].r)
    51         {
    52             node[x].val=a[node[x].l];
    53             return;
    54         }
    55         int mid=(node[x].l+node[x].r)>>1;
    56         node[left_s(x)].l=node[x].l;
    57         node[left_s(x)].r=mid;
    58         build(left_s(x));
    59         node[right_s(x)].l=mid+1;
    60         node[right_s(x)].r=node[x].r;
    61         build(right_s(x));
    62         push_up(x);
    63     }
    64     inline int query(int x,int l,int r)
    65     {
    66         if(node[x].l==l&&node[x].r==r)
    67         {
    68             return node[x].val;
    69         }
    70         int mid=(node[x].l+node[x].r)>>1;
    71         if(r<=mid) return query(left_s(x),l,r);
    72         if(l>mid) return query(right_s(x),l,r);
    73         return min(query(left_s(x),l,mid),query(right_s(x),mid+1,r));
    74     }
    75 }t;
    76 signed main()
    77 {
    78     m=read();n=read();
    79     for(int i=1;i<=m;i++) a[i]=read();
    80     t.init(1,m);
    81     for(int i=1;i<=n;i++)
    82     {
    83         int x=read(),y=read();
    84         int ans=t.query(1,x,y);
    85         write(ans);
    86         printf(" ");
    87     }
    88     return 0;
    89 }

    树状数组代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define int long long
     7 #define maxn 1000000+10
     8 #define INF 2147483647
     9 using namespace std;
    10 inline int read() 
    11 {
    12     int x=0;
    13     bool f=1;
    14     char c=getchar();
    15     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
    16     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
    17     if(f) return x;
    18     return 0-x;
    19 }
    20 inline void write(int x)
    21 {
    22     if(x<0){putchar('-');x=-x;}
    23     if(x>9)write(x/10);
    24     putchar(x%10+'0');
    25 }
    26 int m,n;
    27 int a[maxn];
    28 int tree[maxn];
    29 inline int lowbit(int num)
    30 {
    31     return num&(-num);
    32 }
    33 inline void update(int s,int num)
    34 {
    35     int i=s;
    36     while(i<=m)
    37     {
    38         if(tree[i]>num)
    39             tree[i]=num;
    40         else return; 
    41         i+=lowbit(i);
    42     }
    43 }
    44 inline int query(int l,int r)
    45 {
    46     int res=INF,i=r;
    47     while(i>=l)
    48     {
    49         if(i-lowbit(i)>l)
    50         {
    51             res=min(res,tree[i]);
    52             i-=lowbit(i);
    53         }
    54         else 
    55         {
    56             res=min(res,a[i]);
    57             --i;
    58         }
    59     }
    60     return res;
    61  } 
    62 signed main()
    63 {
    64     memset(tree,127,sizeof(tree));
    65     m=read();n=read();
    66     for(int i=1;i<=m;i++) 
    67     {
    68         a[i]=read();
    69         update(i,a[i]);
    70     }
    71     for(int i=1;i<=n;i++)
    72     {
    73         int x=read(),y=read();
    74         int ans=query(x,y);
    75         write(ans);
    76         printf(" ");
    77     }
    78     return 0;
    79 }

    请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    使用StreamHttpResponse和FileResponse下载文件的注意事项及文件私有化
    Django中@login_required用法简介
    Django之template
    单链表反转的原理和python代码实现
    两个队列实现栈,两个栈实现队列
    Linux--5 mariadb和redis的安装
    Linux--4
    Linux--3
    Linux--2 Linux之文档与目录结构、shell基本命令
    Linux--1 初识
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11745807.html
Copyright © 2020-2023  润新知