题目大意:
给定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\n",ans); } return 0; }