HDU - 6356 Glad You Came(线段树)

题目链接:点击查看

题目大意:给出一个长度为 n 初始时全部为 0 的数组 a ,给出一个数据生成器的 X , Y , Z,每次获得 l , r , val 后,执行操作:对区间 [ l , r ] 内的 a[ i ] = max( val , a[ i ] ) ,最后需要输出 a[ i ] * i 的异或和

题目分析:对于每次操作我们可以暴力更新,如果是纯暴力的话肯定不行,所以我们可以维护一个 mmin 和 mmax 进行剪枝,具体的剪枝方法如下:

  1. 如果 val <= mmin ,直接返回就行
  2. 如果 val >= mmax ,则将当前区间全部更改为 val,然后返回

经过这样的剪枝就可以很轻松的维护好 m 次操作了,最后对于每个位置暴力查询维护答案就好了

代码:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int N=1e5+100;

unsigned int X,Y,Z;

unsigned int function()
{
    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;
}

struct Node
{
	int l,r,lazy,mmin,mmax;
}tree[N<<2];

void pushup(int k)
{
	tree[k].mmin=min(tree[k<<1].mmin,tree[k<<1|1].mmin);
	tree[k].mmax=max(tree[k<<1].mmax,tree[k<<1|1].mmax);
}

void pushdown(int k)
{
	if(tree[k].lazy)
	{
		int lz=tree[k].lazy;
		tree[k].lazy=0;
		tree[k<<1].lazy=tree[k<<1].mmax=tree[k<<1].mmin=lz;
		tree[k<<1|1].lazy=tree[k<<1|1].mmax=tree[k<<1|1].mmin=lz;
	}
}

void build(int k,int l,int r)
{
	tree[k].l=l;
	tree[k].r=r;
	tree[k].lazy=tree[k].mmax=tree[k].mmin=0;
	if(l==r)
		return;
	int mid=l+r>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}

void update(int k,int l,int r,int val)
{
	if(tree[k].mmin>=val)
		return;
	if(tree[k].r<l||tree[k].l>r)
		return;
	if(tree[k].l>=l&&tree[k].r<=r)
	{
		if(val>=tree[k].mmax)
		{
			tree[k].mmin=tree[k].mmax=tree[k].lazy=val;
			return;
		}
	}
	pushdown(k);
	update(k<<1,l,r,val);
	update(k<<1|1,l,r,val);
	pushup(k);
}

int query(int k,int pos)
{
	if(tree[k].l==tree[k].r)
		return tree[k].mmin;
	pushdown(k);
	int mid=tree[k].l+tree[k].r>>1;
	if(pos<=mid)
		return query(k<<1,pos);
	else
		return query(k<<1|1,pos);
}

int main()
{
#ifndef ONLINE_JUDGE
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
	int w;
	cin>>w;
	while(w--)
	{
		int n,m;
		scanf("%d%d%u%u%u",&n,&m,&X,&Y,&Z);
		build(1,1,n);
		while(m--)
		{
			int l=function()%n+1;
            int r=function()%n+1;
            int val=function()%(1<<30);
            if(l>r)
            	swap(l,r);
            update(1,l,r,val);
		}
		LL ans=0;
		for(int i=1;i<=n;i++)
			ans^=1LL*i*query(1,i);
		printf("%lld\n",ans);
	}










    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45458915/article/details/106931549
今日推荐