zoukankan      html  css  js  c++  java
  • HDU 1754

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754

    Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

    Problem Description
    很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
    这让很多学生很反感。
    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
     
    Input
    本题目包含多组测试,请处理到文件结束。
    在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
    学生ID编号分别从1编到N。
    第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
    接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
    当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
    当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
     
    Output
    对于每一次询问操作,在一行里面输出最高成绩。
     
    Sample Input
    5 6
    1 2 3 4 5
    Q 1 5
    U 3 6
    Q 3 4
    Q 4 5
    U 2 9
    Q 1 5
     
    Sample Output
    5
    6
    5
    9
    Hint
    Huge input,the C function scanf() will work better than cin

    只需要对线段树模板进行修改即可:

    (单点直接修改,区间查询线段树:)

    #include<cstdio>
    #include<algorithm>
    #define MAXN 200000+5
    using namespace std;
    typedef long long ll;
    struct Node{
        int l,r;
        ll val;
    }node[4*MAXN];
    int n,m,a[MAXN];
    void pushup(int root)
    {
        node[root].val=max(node[root*2].val,node[root*2+1].val);
    }
    void build(int root,int l,int r)
    {
        node[root].l=l; node[root].r=r;
        node[root].val=0;
        if(l==r) node[root].val=a[l];
        else
        {
            int mid=l+(r-l)/2;
            build(root*2,l,mid);
            build(root*2+1,mid+1,r);
            pushup(root);
        }
    }
    void update(int root,int pos,int val)
    {
        if(node[root].l>pos || node[root].r<pos) return;
        if(node[root].l==pos && node[root].r==pos)
        {
            node[root].val=val;
            return;
        }
        else
        {
            update(root*2,pos,val);
            update(root*2+1,pos,val);
            pushup(root);
        }
    }
    ll query(int root,int st,int ed)
    {
        if(ed<node[root].l || node[root].r<st) return 0;
        if(st<=node[root].l && node[root].r<=ed) return node[root].val;
        else
        {
            ll a=query(root*2,st,ed);
            ll b=query(root*2+1,st,ed);
            return max(a,b);
        }
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(int i=1;i<=n;i++) scanf("%d",&a[i]);
            build(1,1,n);
            char op[2]; int A,B;
            for(int i=1;i<=m;i++)
            {
                scanf("%s",&op);
                scanf("%d%d",&A,&B);
                if(op[0]=='Q') printf("%I64d
    ",query(1,A,B));
                if(op[0]=='U') update(1,A,B);
            }
        }
    }

    当然,我们想到,如果不是对模板进行大改(去掉了lazy)的话,可以得到区间直接修改,区间查询的线段树:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define MAXN 200000+5
     4 using namespace std;
     5 typedef long long ll;
     6 struct Node{
     7     int l,r;
     8     ll val,lazy;
     9     void update(ll x)
    10     {
    11         val=(r-l+1)*x;
    12         lazy=x;
    13     }
    14 }node[4*MAXN];
    15 int n,m,a[MAXN];
    16 void pushdown(int root)
    17 {
    18     if(node[root].lazy)
    19     {
    20         node[root*2].update(node[root].lazy);
    21         node[root*2+1].update(node[root].lazy);
    22         node[root].lazy=0;
    23     }
    24 }
    25 void pushup(int root)
    26 {
    27     node[root].val=max(node[root*2].val,node[root*2+1].val);
    28 }
    29 void build(int root,int l,int r)
    30 {
    31     node[root].l=l; node[root].r=r;
    32     node[root].val=0; node[root].lazy=0;
    33     if(l==r) node[root].val=a[l];
    34     else
    35     {
    36         int mid=l+(r-l)/2;
    37         build(root*2,l,mid);
    38         build(root*2+1,mid+1,r);
    39         pushup(root);
    40     }
    41 }
    42 void update(int root,int st,int ed,int val)
    43 {
    44     if(st>node[root].r || ed<node[root].l) return;
    45     if(st<=node[root].l && node[root].r<=ed) node[root].update(val);
    46     else
    47     {
    48         pushdown(root);
    49         update(root*2,st,ed,val);
    50         update(root*2+1,st,ed,val);
    51         pushup(root);
    52     }
    53 }
    54 ll query(int root,int st,int ed)
    55 {
    56     if(ed<node[root].l || node[root].r<st) return 0;
    57     if(st<=node[root].l && node[root].r<=ed) return node[root].val;
    58     else
    59     {
    60         pushdown(root);
    61         ll a=query(root*2,st,ed);
    62         ll b=query(root*2+1,st,ed);
    63         pushup(root);
    64         return max(a,b);
    65     }
    66 }
    67 int main()
    68 {
    69     while(scanf("%d%d",&n,&m)!=EOF)
    70     {
    71         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    72         build(1,1,n);
    73         char op[2]; int A,B;
    74         for(int i=1;i<=m;i++)
    75         {
    76             scanf("%s",&op);
    77             scanf("%d%d",&A,&B);
    78             if(op[0]=='Q') printf("%I64d
    ",query(1,A,B));
    79             if(op[0]=='U') update(1,A,A,B);
    80         }
    81     }
    82 }

                                                                                                                                                                                                                               

    题目链接:https://cn.vjudge.net/problem/UVA-12299

    由于该题的shift操作的要求数据量不大,所以直接进行暴力的单点修改即可。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define MAXN 100000+5
     5 #define INF 0x3f3f3f3f
     6 using namespace std;
     7 int n,m,a[MAXN];
     8 struct Node{
     9     int l,r,val;
    10 }node[4*MAXN];
    11 void pushup(int root)
    12 {
    13     node[root].val=min(node[root*2].val,node[root*2+1].val);
    14 }
    15 void build(int root,int l,int r)
    16 {
    17     node[root].l=l; node[root].r=r;
    18     node[root].val=0;
    19     if(l==r) node[root].val=a[l];
    20     else
    21     {
    22         int mid=l+(r-l)/2;
    23         build(root*2,l,mid);
    24         build(root*2+1,mid+1,r);
    25         pushup(root);
    26     }
    27 }
    28 void update(int root,int pos,int val)
    29 {
    30     if(node[root].l>pos || node[root].r<pos) return;
    31     if(node[root].l==pos && node[root].r==pos)
    32     {
    33         node[root].val=val;
    34         return;
    35     }
    36     else
    37     {
    38         update(root*2,pos,val);
    39         update(root*2+1,pos,val);
    40         pushup(root);
    41     }
    42 }
    43 int query(int root,int st,int ed)
    44 {
    45     if(ed<node[root].l || node[root].r<st) return INF;
    46     if(st<=node[root].l && node[root].r<=ed) return node[root].val;
    47     else return min(query(root*2,st,ed),query(root*2+1,st,ed));
    48 }
    49 int main()
    50 {
    51     scanf("%d%d",&n,&m);
    52     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    53     build(1,1,n);
    54     char op[31];
    55     int num[30],cnt;
    56     for(int i=1;i<=m;i++)
    57     {
    58         scanf("%s",op);
    59         memset(num,0,sizeof(num)); cnt=1;
    60         for(int j=6,_len=strlen(op);j<_len;j++)
    61         {
    62             if(op[j]==',') cnt++;
    63             if('0'<=op[j] && op[j]<='9') num[cnt]=num[cnt]*10+(op[j]-'0');
    64         }
    65         if(op[0]=='q')
    66         {
    67             printf("%d
    ",query(1,num[1],num[2]));
    68         }
    69         if(op[0]=='s')
    70         {
    71             int tmp=query(1,num[1],num[1]);
    72             for(int i=2;i<=cnt;i++)
    73             {
    74                 update(1,num[i-1],query(1,num[i],num[i]));
    75             }
    76             update(1,num[cnt],tmp);
    77         }
    78     }
    79 }

    感觉这题难道不是难在线段树,难在输入……

  • 相关阅读:
    linux学习资料收藏
    java 自动补全
    iframe
    XSLT 创建CDATA节点
    java 线程
    SQL(ORACLE)
    ubuntu下php无法载入mysql扩展
    Laravel 5.2 新特性系列 —— 多用户认证功能实现详解
    Windows环境下的NodeJS+NPM+Bower安装配置步骤
    关于Laravel 5 中 Html,Form 安装以及修改使用标签
  • 原文地址:https://www.cnblogs.com/dilthey/p/7482518.html
Copyright © 2011-2022 走看看