Glad You Came(线段树更新区间内比v小的数)

原题:hdu 6356

解析:

太杂了,所以那部分就不解释了,去杂后就是一个区间更新的问题

每次更新l,r,v,区间内比v小的数会变成v

主要思路就是记下区间的min,如果一个更新区间的最小值都比v大就说明不用更新从而起到一个剪枝的作用

代码:


#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int mod=(1<<30);
const int maxn=100005;
typedef unsigned ll;
ll f[15000000], x,y,z;
int n,m;
unsigned rng()
{
    unsigned t;
    x^=x<<11;
    x^=x>>4;
    x^=x<<5;
    x^=x>>14;
    t=x;
    x=y;
    y=z;
    z=x^y^t;
    return z;
}
struct node{
    int maxx,minn,lazy;
}e[maxn<<2];
void pushdown(int rt){
    if(e[rt].lazy){
        e[lson].lazy=e[rt].lazy;
        e[rson].lazy=e[rt].lazy;
        e[lson].maxx=e[rt].lazy;
        e[rson].maxx=e[rt].lazy;
        e[lson].minn=e[rt].lazy;
        e[rson].minn=e[rt].lazy;
        e[rt].lazy=0;
    }
}
void update(int nowl,int nowr,int l,int r,int rt,ll aim){
    if(e[rt].minn>=aim)return;//key
    if(nowl>=l&&nowr<=r){
        if(e[rt].maxx<=aim){
            e[rt].maxx=aim;
            e[rt].minn=aim;
            e[rt].lazy=aim;
            return ;
        }
        else if(e[rt].minn>=aim){
            return ;
        }
    }
    pushdown(rt);
    int mid=(nowl+nowr)/2;
    if(mid>=l) update(nowl,mid,l,r,lson,aim);
    if(mid<r) update(mid+1,nowr,l,r,rson,aim);
    e[rt].maxx=max(e[lson].maxx,e[rson].maxx);
    e[rt].minn=min(e[lson].minn,e[rson].minn);
}
ll query(int nowl,int nowr,int l,int r,int rt){
    if(nowl>=l&&nowr<=r){
        return e[rt].maxx;
    }
    pushdown(rt);
    int mid=(nowl+nowr)/2;
    if(mid>=l) return query(nowl,mid,l,r,lson);
    if(mid<r) return query(mid+1,nowr,l,r,rson);
}
int main(){
    int t;
    cin>>t;
    while(t--){
        scanf("%d%d%u%u%u",&n,&m,&x,&y,&z);
        memset(e,0,sizeof(e));
        for(int i=1;i<=3*m;i++)
            f[i]=rng();
        for(int i=1;i<=m;i++){

            int l=min(f[3*i-2]%n+1,f[3*i-1]%n+1);
            int r=max(f[3*i-2]%n+1,f[3*i-1]%n+1);
            ll aim=f[3*i]%mod;
            update(1,n,l,r,1,aim);
        }
        unsigned long long ans=0;
        for(int i=1;i<=n;i++){
            unsigned long long nows=query(1,n,i,i,1);
            ans^=(i*nows);
        }
        cout<<ans<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/81488199