http://acm.hdu.edu.cn/showproblem.php?pid=6356
题意:给你3*m个数的生成规则,用来生成m个区间和对应的值,将区间内小于此值的改为此值.问最后所有值乘对应位置的异或值.
思路:直接线段树区间更新,不要懒惰标记也不要建树,发现不用memset初始,反而跟快。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+10;
const int inf=0x7fffffff;
unsigned x,y,z;
int n,m;
unsigned tang()
{
unsigned t;
x^=x<<11;
x^=x>>4;
x^=x<<5;
x^=x>>14;
t=x;
x=y;
y=z;
z=t^x^y;
return z;
}
ll minn[maxn<<2];
void update(int l,int r,int L,int R,ll k,int h)
{
if(minn[h]>=k)
{
return;
}
if(l==r)
{
minn[h]=max(minn[h],k);
return;
}
int mid=(l+r)/2;
if(L<=mid)update(l,mid,L,R,k,h*2);
if(R>mid)update(mid+1,r,L,R,k,h*2+1);
minn[h]=min(minn[h*2],minn[h*2+1]);
}
ll ans[111111];
void query(int x,int l,int r)
{
if(l==r)
{
ans[l]=minn[x];
return ;
}
int mid=(l+r)/2;
query(x*2,l,mid);
query(x*2+1,mid+1,r);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>m>>x>>y>>z;
for(int i=1;i<=4*n;i++)
minn[i]=0;
for(int i=1;i<=m;i++)
{
unsigned h=tang(),hh=tang(),hhh=tang();
int l=min((h%n)+1,(hh%n)+1);
int r=max((h%n)+1,(hh%n)+1);
int v=hhh%(1<<30);
update(1,n,l,r,v,1);
}
query(1,1,n);
long long aa=0;
for(long long i=1;i<=n;i++)
{
aa=aa^(i*ans[i]);
}
cout<<aa<<endl;
}
return 0;
}