P1531 && HDU – 1754 I Hate It(线段树)

发布于 2020-10-06  0 次阅读


P1531 I Hate It

题目大意:

n个学生,告知你每位学生的成绩,m次查询,
每一行有一个字符 C (只取’Q’或’U’) ,和两个正整数A,B。当C为’Q’的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。当C为’U’的时候,表示这是一条更新操作,如果当前A学生的成绩低于B,则把ID为A的学生的成绩更改为B,否则不改动。

思路:

很明显的区间查询,单点修改,维护区间最大值即可
线段树模板题

AC Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+9;
struct node{
    int score;
}a[N];
struct segtree{
    int v, tag;
}tr[N<<2];
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}
inline int lc(int p)   {return p<<1;}
inline int rc(int p)   {return p<<1|1;}
inline void build(int k, int l, int r){
    if(l==r)    {tr[k].v=a[l].score; return ;}
    int mid=(l+r)>>1;
    build(lc(k), l, mid);
    build(rc(k), mid+1, r);
    tr[k].v=max(tr[lc(k)].v,tr[rc(k)].v);
}
inline void f(int p, int k){
    tr[p].v=max(tr[p].v, k);
    tr[p].tag=max(tr[p].tag, k);
}
inline void push_down(int p){
    f(lc(p), tr[p].tag);
    f(rc(p), tr[p].tag);
    tr[p].tag=0;
}
inline void push_up(int p)  {tr[p].v=max(tr[lc(p)].v, tr[rc(p)].v);}
inline void updata(int p, int l, int r, int x, int y, int k){
    if(x>r || y<l)  return ;
    if(l<=x && y<=r){
        tr[p].v=max(tr[p].v, k);
        tr[p].tag=max(tr[p].tag,k);
        return ;
    }  
    int mid=(x+y)>>1;
    if(tr[p].tag) push_down(p);
    updata(lc(p), l, r, x, mid, k);
    updata(rc(p), l, r, mid+1, y, k);
    push_up(p);
}
inline int query(int p, int l, int r, int x, int y){
    if(x>r || y<l)  return 0;
    if(l<=x && y<=r) return tr[p].v;
    int mid=(x+y)>>1;
    if(tr[p].tag) push_down(p);
    return max(query(lc(p), l, r, x, mid), query(rc(p), l, r, mid+1, y));
}
int main(){
    int n=read();
    int m=read();
    for(int i=1; i<=n; i++){
        a[i].score=read();
    }
    build(1,1,N);
    char op;
    int x, y;
    for(int i=1; i<=m; i++){
        cin>>op>>x>>y;
        if(op=='Q') cout<<query(1,x,y,1,N)<<endl;
        if(op=='U'){
            int s1=query(1,x,x,1,N);
            if(s1<y)   updata(1,x,x,1,N,y);
        }
    }
    return 0;
}

I Hate It

题目大意:

跟洛谷的题差不多,只不过修改是直接修改,而不是比之前的值大才修改
注意多组输入!
注意多组输入!
注意多组输入!

AC Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+9;
struct node{
    int score;
}a[N];
struct segtree{
    int v, tag;
}tr[N<<2];
inline int read()
{
    int ans=0;
    char last=' ',ch=getchar();
    while(ch<'0'||ch>'9') last=ch,ch=getchar();
    while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
    if(last=='-') ans=-ans;
    return ans;
}
inline int lc(int p)   {return p<<1;}
inline int rc(int p)   {return p<<1|1;}
inline void push_up(int p)  {tr[p].v=max(tr[lc(p)].v, tr[rc(p)].v);}
inline void build(int k, int l, int r){
    if(l==r)    {tr[k].v=a[l].score; return ;}
    int mid=(l+r)>>1;
    build(lc(k), l, mid);
    build(rc(k), mid+1, r);
    push_up(k);
}

inline void updata(int p, int l, int r, int x, int y, int k){
    if(x>r || y<l)  return ;
    if(l<=x && y<=r){
        tr[p].v=k;
        return ;
    }  
    int mid=(x+y)>>1;
    updata(lc(p), l, r, x, mid, k);
    updata(rc(p), l, r, mid+1, y, k);
    push_up(p);
}
inline int query(int p, int l, int r, int x, int y){
    if(x>r || y<l)  return 0;
    if(l<=x && y<=r) return tr[p].v;
    int mid=(x+y)>>1;
    return max(query(lc(p), l, r, x, mid), query(rc(p), l, r, mid+1, y));
}
int main(){
    int n, m;
    while(~scanf("%d%d", &n, &m)){
        for(int i=1; i<=n; i++) a[i].score=read();
        build(1,1,n);
        char op;
        int x, y;
        for(int i=1; i<=m; i++){
            cin>>op>>x>>y;
            if(op=='Q') cout<<query(1,x,y,1,n)<<endl;
            if(op=='U') updata(1,x,x,1,n,y);
        }
    }
    return 0;
}

平平无奇的在校大学生