【做题笔记】P1531 I Hate It

线段树裸题。

需要注意的地方:

对于一次单点修改操作,需要先判断是否需要修改。注意题目中是“如果当前A学生的成绩低于B,则把ID为A的学生的成绩更改为B,否则不改动。”。所以判断条件应该是 if(w=='U')if(a[x]。另外,由于在 \(\text{change}\) 时只是修改了这个元素在线段树中的值,所以在调用函数后,记得把这个数在原序列中的值也改动。

#include 
#include 
#include 

using namespace std;

struct SegmentTree
{
    int l,r;
    long long data;
    #define l(x) t[x].l
    #define r(x) t[x].r
    #define m(x) t[x].data
};
SegmentTree t[20000001*4];

long long n,m,a[20000001];

inline int read()
{
    int w=1,s=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    return s*w;
}

void build(int p,int l,int r)
{
    l(p)=l,r(p)=r;
    if(l==r){m(p)=a[l];return ;}
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    m(p)=max(m(p*2),m(p*2+1));
}

void change(int p,int x,int v)
{
    if(l(p)==r(p)){m(p)=v;return ;}
    int mid=(l(p)+r(p))/2;
    if(x<=mid)change(p*2,x,v);
    else change(p*2+1,x,v);
    m(p)=max(m(p*2),m(p*2+1));
}

long long ask(int p,int l,int r)
{
    if(l<=l(p)&&r>=r(p))return m(p);
    int mid=(l(p)+r(p))/2;
    long long ans=-(1<<30);
    if(l<=mid)ans=max(ans,ask(p*2,l,r));
    if(r>mid)ans=max(ans,ask(p*2+1,l,r));
    return ans;
}

int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    build(1,1,n);
    while(m--)
    {
        char w;int x,y;
        cin>>w;x=read(),y=read();
        if(w=='U')if(a[x]

你可能感兴趣的:(【做题笔记】P1531 I Hate It)