zoukankan      html  css  js  c++  java
  • HDU 6356 (线段树-l,r 之间小于val 的变val+单点求值)

    题目描述:

        给你一个长度为n的最开始为0的数以及m个更新操作以及数据生成器参数X,Y,Z。每次操作,将由数据生成器生成出li,ri,vi。让你从区间[li,ri]中,将所有小于vi的数变为vi。最后让你求从1到n的 i*ai的亦或和。

    分析:区间操作优先考虑线段树 , 那线段树存储什么数值呢? 我们知道如果l ,r 的最大值<=val , 那整个l区间都要改成val , 如果最小值>=val  那这个区间就不用修改 ; 那不是这种情况怎么办呢?不可能是for一遍吧 , 其实只要一次跟新操作就好 , 线段树的区间更新是将整课树都遍历一遍 ,所以我们只要在遍历的过程中判断是否到达叶子结点就好拉;

    #include <iostream>
    #include <string.h>
    #include <algorithm>
    #include <stdio.h>
    #include <math.h>
    #include <queue>
    #define MAXN 5000001
    #define inf 0x3f3f3f3f
    
    using namespace std;
    unsigned int x,y,z,w,v,b[MAXN*3];
    int n,m;
    long long ans;
    unsigned int 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;
    }
    struct node{
        int l,r;//区间[l,r]
        int add;//区间的延时标记
        int mx; //区间最大值
        int mn; //区间最小值
    }tree[MAXN<<2];//一定要开到4倍多的空间
    
    void pushup(int index){
        tree[index].mx = max(tree[index<<1].mx,tree[index<<1|1].mx);
        tree[index].mn = min(tree[index<<1].mn,tree[index<<1|1].mn);
    }
    void pushdown(int index){
        //说明该区间之前更新过
        //要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新
        if(tree[index].add > 0){
            //替换原来的值
    
            tree[index<<1].mx = tree[index].add;
            tree[index<<1|1].mx = tree[index].add;
            tree[index<<1].mn = tree[index].add;
            tree[index<<1|1].mn = tree[index].add;
            tree[index<<1].add = tree[index].add;
            tree[index<<1|1].add = tree[index].add;
            tree[index].add = 0;
    
        }
    }
    void build(int l,int r,int index){
        tree[index].l = l;
        tree[index].r = r;
        tree[index].add = 0;//刚开始一定要清0
        if(l == r){
    
            tree[index].mn = tree[index].mx = 0;
            return ;
        }
        int mid = (l+r)>>1;
        build(l,mid,index<<1);
        build(mid+1,r,index<<1|1);
        pushup(index);
    }
    void updata(int l,int r,int index,int val){
    
        if(tree[index].l==tree[index].r)///到达叶子节点
        {
            tree[index].mn=max(tree[index].mn , val);
            tree[index].mx=max(tree[index].mx , val);
            return ;
        }
        if(l <= tree[index].l && r >= tree[index].r){
    
            if(tree[index].mx<=val)
            {
            tree[index].mn = val;
            tree[index].mx = val;
            tree[index].add = val;//延时标记
            return ;
            }
            if(tree[index].mn>=val) return ;
        }
        if(tree[index].mn>=val) return ;
        pushdown(index);
        int mid = (tree[index].l+tree[index].r)>>1;
        if(l <= mid){
            updata(l,r,index<<1,val);
        }
        if(r > mid){
            updata(l,r,index<<1|1,val);
        }
        pushup(index);
    }
    int query(int l,int r,int index,int pos){
        if(l==r)
        {
            return tree[index].mn;
        }
        int mid=(l+r)>>1;
        pushdown(index);
        if(pos<=mid) return query(l,mid , index<<1 , pos);
        else return query(mid+1,r ,index<<1|1 , pos);
    }
    int main()
    {
    
          int t,l,r;
          scanf("%d",&t);
          while(t--)
          {
              scanf("%d%d%u%u%u",&n , &m , &x , &y , &z);
              build(1,n,1);
              for(int i=1 ; i<=max(n,3*m) ; i++)///数据生成器
              b[i] = fun();
              for(int i=1 ; i<=m ; i++)
              {
                 l = min(b[3*i-2]%n+1 , b[3*i-1]%n+1);
                 r = max(b[3*i-2]%n+1 , b[3*i-1]%n+1);
                 v = b[3*i]%(1<<30);
                 updata(l,r,1,v);
              }
              ans=0;
              for(int i=1 ; i<=n ; i++)
              ans^=(long long)i*query(1,n,1,i);
              printf("%lld
    ",ans);
          }
    
        return 0;
    }
    View Code
  • 相关阅读:
    二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组
    归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
    22-Java-Hibernate框架(二)
    21-Java-Hibernate框架(一)
    操作系统-5-进程管理(二)
    操作系统-4-进程管理(一)
    操作系统-3-操作系统引论
    操作系统-2-存储管理之LRU页面置换算法(LeetCode146)
    20-Java-正则表达式
    19-Java-核心类库2-包装类、Integer类、String类、StringBuffer类、StringBuilder类
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/10338328.html
Copyright © 2011-2022 走看看