hdu6354 /// 线段树

题目大意:

给定n m x y z

长度为n的序列初始为0

接下来m个操作 l r v 将l r区间内比v小的数都变成v

l r v由x y z和给定的函数生成

线段树维护区间 最大值 最小值 再加 lazy标记

当v大于某个区间的最大值时 整个区间都要变成v 用lazy标记

当v小于某个区间的最小值时 整个区间都不需要操作

题解:https://blog.csdn.net/weixin_39453270/article/details/81462219

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long
#define mem(i,j) memset(i,j,sizeof(i))
const int N=1e5+5;
const int MOD=1e9+7;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1
int maxi[N<<2], mini[N<<2], lazy[N<<2];
void pushUp(int rt) {
    maxi[rt]=max(maxi[rt<<1],maxi[rt<<1|1]);
    mini[rt]=min(mini[rt<<1],mini[rt<<1|1]);
}
void pushDown(int rt) {
    if(lazy[rt]!=-1) {
        mini[rt<<1]=max(mini[rt<<1],lazy[rt]);
        mini[rt<<1|1]=max(mini[rt<<1|1],lazy[rt]);
        maxi[rt<<1]=max(maxi[rt<<1],lazy[rt]);
        maxi[rt<<1|1]=max(maxi[rt<<1|1],lazy[rt]);
        lazy[rt<<1]=max(lazy[rt<<1],lazy[rt]);
        lazy[rt<<1|1]=max(lazy[rt<<1|1],lazy[rt]);
        lazy[rt]=-1;
    }
}
void build(int l,int r,int rt) {
    lazy[rt]=-1;
    if(l==r) {
        mini[rt]=maxi[rt]=0;
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushUp(rt);
}
void update(int L,int R,int v,int l,int r,int rt) {
    if(l==r) {
        mini[rt]=max(mini[rt],v);
        maxi[rt]=max(maxi[rt],v);
        return;
    }
    if(L<=l && r<=R) {
        if(maxi[rt]<=v) {
            maxi[rt]=mini[rt]=v;
            lazy[rt]=max(lazy[rt],v);
            return;
        }
    }
    if(mini[rt]>=v) return;
    pushDown(rt);
    int m=(l+r)>>1;
    if(L<=m) update(L,R,v,lson);
    if(m<R) update(L,R,v,rson);
    pushUp(rt);
}
LL query(int pos,int l,int r,int rt) {
    if(l==r) return 1LL*pos*mini[rt];
    pushDown(rt);
    int m=(l+r)>>1;
    if(pos<=m) return query(pos,lson);
    else return query(pos,rson);
}

int n, m;
unsigned int x, y, z;
unsigned int RNG61() {
    x=x^(x<<11);
    x=x^(x>>4);
    x=x^(x<<5);
    x=x^(x>>14);
    unsigned int w=x^(y^z);
    x=y, y=z, z=w;
    return z;
}
int main()
{
    int t; scanf("%d",&t);
    while(t--) {
        scanf("%d%d%u%u%u",&n,&m,&x,&y,&z);
        build(root);
        for(int i=1;i<=m;i++) {
            int l=RNG61()%n+1;
            int r=RNG61()%n+1;
            int v=RNG61()%(1<<30);
            if(l>r) swap(l,r);
            update(l,r,v,root);
        }
        LL ans=0;
        for(int i=1;i<=n;i++)
            ans^=query(i,root);
        printf("%lld
",ans);
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zquzjx/p/10332416.html