待研究,标称做法,反向跑ST表
参考博客
mycode:
线段树,待研究,比PPT老师的慢了一倍
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lson rt<<1
#define rson rt<<1|1
#define MID int m =(l+r)/2
const int inf =0x3f3f3f3f;
const int maxn = 31234567;
struct node
{
ll lazy,sum;
ll Min,Max;
}tree[400000];
int n,m;
long long l[maxn],r[maxn],v[maxn],f[maxn],a[maxn];
long long mm = 1073741824ll;
void push_up(int rt)
{
tree[rt].Min = min(tree[lson].Min,tree[rson].Min);
}
void push_down(int rt,int l,int r)
{
if(tree[rt].lazy)
{
ll z = tree[rt].Min;
tree[rt].lazy=0;
tree[lson].lazy = z;
tree[rson].lazy = z;
tree[rson].Min = max(tree[rson].Min,z);
tree[lson].Min = max(tree[lson].Min,z);
//updata函数怎么操作,lazy就怎么操作
tree[rt].lazy =0;
}
}
ll sum;
void query(int rt,int l,int r)
{
//if(pos<l||pos>r)return;
if(l>r)return;
if(l==r)
{
sum^=(l*tree[rt].Min);
return;
}
MID;
push_down(rt,l,r);
query(lson,l,m);
query(rson,m+1,r);
//push_up(rt);
}
void build(int rt,int l,int r)
{
if(l>r) //加了这里,下面build函数就不用if判断了
{
//tree[rt].Min = v[l];
return ;
}
tree[rt].lazy = 0;
//tree[rt].Min =0;
if(l==r)
{
tree[rt].Min =0;
return ;
}
MID;
build(lson,l,m);
build(rson,m+1,r);
push_up(rt);
}
void updata(int rt,int l,int r,int ql,int qr,ll v)
{
if(ql>r||qr<l)return ;
if(tree[rt].Min>=v)return;//剪枝,如果区间最小值还大于v
//则说明这个区间都不用更新了,因为v的作用是去更新a数组
if(ql<=l&&r<=qr)
{
tree[rt].Min = max(tree[rt].Min,v);
//v的作用是去更新a数组
tree[rt].lazy =v;
return;
}
MID;
push_down(rt,l,r);
updata(lson,l,m,ql,qr,v);
updata(rson,m+1,r,ql,qr,v);
push_up(rt);
}
unsigned x,y,z,w;
unsigned fun()
{
x = x^(x<<11);
x= x^(x>>4);
x = x^(x<<5);
x = x^(x>>14);
w = x^(y^z);
x = y;
y = z;
z = w;
return z;
}
int main()
{
//ios::sync_with_stdio(false);
int t;
cin>>t;
while(t--)
{
sum = 0;
//memset(a,0,sizeof a);
// cin>>n>>m>>x>>y>>z;
scanf("%d%d%u%u%u",&n,&m,&x,&y,&z);
for(int i=1;i<=m*3;i++)
f[i] = fun();
build(1,1,n);
for(int i=1;i<=m;i++)
{
l[i] = min(f[3*i-2]%n+1,f[3*i-1]%n+1);
r[i] = max(f[3*i-2]%n+1,f[3*i-1]%n+1);
v[i] = f[3*i]%mm;
updata(1,1,n,l[i],r[i],v[i]);
}
// for(int i=1;i<=m;i++)
// {
//
//// for(int j=l[i];j<=r[i];j++)
//// {
//// if(a[j]<v[i])
//// {
//// a[j] = v[i];
//// }
//// }
// }
// long long ans= 0;
// for(int i=1;i<=n;i++)
// {
// ans^=(i*a[i]);
// }
sum =0;
query(1,1,n);
printf("%lld\n",sum);
}
return 0;
}
PPT老师的code:
#include <bits/stdc++.h>
#define PI 3.14159265358979323846
using namespace std;
struct segtree
{
int l,r,lazy;
long long num;
}a[400000];
long long sum,cnt;
unsigned int x,y,z,b[15000001];
void f()
{
unsigned int w;
x=(x^(x<<11));
x=(x^(x>>4));
x=(x^(x<<5));
x=(x^(x>>14));
w=(x^(y^z));
x=y;
y=z;
z=w;
}
void build(int l,int r,int pos)
{
int mid;
a[pos-1].l=l;
a[pos-1].r=r;
a[pos-1].lazy=0;
a[pos-1].num=0;
if(l==r)
{
return;
}
mid=(l+r)/2;
build(l,mid,pos*2);
build(mid+1,r,pos*2+1);
}
void push(int pos)
{
a[pos-1].num=min(a[pos*2-1].num,a[pos*2].num);
}
void down(int pos)
{
if(a[pos-1].lazy==1)
{
a[pos*2-1].num=max(a[pos*2-1].num,a[pos-1].num);
a[pos*2].num=max(a[pos*2].num,a[pos-1].num);
a[pos*2-1].lazy=a[pos*2].lazy=a[pos-1].lazy;
a[pos-1].lazy=0;
}
}
void update(int l,int r,int pos,long long val)
{
int mid;
if(a[pos-1].num>=val)
{
return;
}
if(a[pos-1].l>r||a[pos-1].r<l)
{
return;
}
if(a[pos-1].l>=l&&a[pos-1].r<=r)
{
a[pos-1].num=val;
a[pos-1].lazy=1;
return;
}
down(pos);
mid=(a[pos-1].l+a[pos-1].r)/2;
if(l<=mid)
{
update(l,r,pos*2,val);
}
if(r>mid)
{
update(l,r,pos*2+1,val);
}
push(pos);
}
void query(int pos)
{
if(a[pos-1].l==a[pos-1].r)
{
sum=sum^(a[pos-1].num*cnt);
cnt++;
return;
}
down(pos);
query(pos*2);
query(pos*2+1);
}
int main()
{
int t,n,m,i,mod=(1<<30);
scanf("%d",&t);
while(t--)
{
scanf("%d %d %u %u %u",&n,&m,&x,&y,&z);
sum=0;
cnt=1;
build(1,n,1);
for(i=1;3*m>=i;i++)
{
f();
b[i]=z;
}
for(i=1;m>=i;i++)
{
update(min(b[3*i-2]%n+1,b[3*i-1]%n+1),max(b[3*i-2]%n+1,b[3*i-1]%n+1),1,b[3*i]%mod);
}
query(1);
printf("%lld\n",sum);
}
return 0;
}