Codeforces 1146 E Hot is Cold —— 线段树区间赋值和区间正负翻转

This way

题意:

给你长为n的数组,每次有两种操作:
> x 将所有大于x的数*-1
< x 将所有小于x的数*-1
问你经过q次操作之后,最终的数组是什么样子的

题解:

这种题目一看就不能直接做,然后它的数的范围只有-1e5~1e5,其实就算再大,离散化一下也能做。那么接下来就是分情况了,首先第一种操作:
假设x>=0
在这里插入图片描述
那么就相当于>x的所有数都要乘-1,<-x的都要乘1。
那么如果x<0
在这里插入图片描述
-x+1到x-1的所有数,无论他们是正是负都要变换一下符号位,也就是*-1,然后两边的话就像上边一样即可。
对于<的情况也类似。
就是赋值和下传标记的时候注意一下。
我这里f1表示翻转操作,f2表示赋值操作。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10,ad=1e5+2;
int val[N*4],f1[N*4],f2[N*4];
int a[N];
void push_down(int root){
    if(f1[root]){
        val[root<<1]*=-1;
        val[root<<1|1]*=-1;
        f1[root<<1]^=1;
        f1[root<<1|1]^=1;
        f2[root<<1]*=-1;
        f2[root<<1|1]*=-1;
        f1[root]=0;
    }
    if(f2[root]){
        val[root<<1]=val[root<<1|1]=f2[root];
        f1[root<<1]=f1[root<<1|1]=0;
        f2[root<<1]=f2[root<<1|1]=f2[root];
        f2[root]=0;
    }
}
void update(int l,int r,int root,int ql,int qr,int op,int v){
    if(l>=ql&&r<=qr){
        if(op==1)
            val[root]*=-1,f1[root]^=1,f2[root]*=-1;
        else
            val[root]=v,f2[root]=v,f1[root]=0;
        return ;
    }
    int mid=l+r>>1;
    push_down(root);
    if(mid>=ql)
        update(l,mid,root<<1,ql,qr,op,v);
    if(mid<qr)
        update(mid+1,r,root<<1|1,ql,qr,op,v);
}
int query(int l,int r,int root,int p){
    if(l==r)
        return val[root];
    int mid=l+r>>1;
    push_down(root);
    if(mid>=p)
        return query(l,mid,root<<1,p);
    else
        return query(mid+1,r,root<<1|1,p);
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=ad*2*4;i++)
        val[i]=1;
    while(k--){
        char s[2];
        int x;
        scanf("%s%d",s,&x);
        if(s[0]=='>'){
            if(x>=0){
                update(1,2*ad,1,x+1+ad,2*ad,2,-1);
                update(1,2*ad,1,1,ad-x-1,2,1);
                //printf("%d\n",query(1,2*ad,1,2+ad));
            }
            else{
                update(1,2*ad,1,ad+x+1,ad-x-1,1,1);
                update(1,2*ad,1,1,ad+x,2,1);
                update(1,2*ad,1,ad-x,2*ad,2,-1);
            }
        }
        else{
            if(x>0){
                update(1,2*ad,1,ad-x+1,ad+x-1,1,1);
                update(1,2*ad,1,1,ad-x,2,-1);
                update(1,2*ad,1,ad+x,2*ad,2,1);
            }
            else{
                update(1,2*ad,1,1,ad+x-1,2,-1);
                update(1,2*ad,1,ad-x+1,2*ad,2,1);
            }
        }
    }
    for(int i=1;i<=n;i++)
        printf("%d%c",a[i]*query(1,2*ad,1,ad+a[i])," \n"[i==n]);
    return 0;
}

发布了584 篇原创文章 · 获赞 33 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/tianyizhicheng/article/details/105471136
今日推荐