• HDU6356:Glad You Came ST表的巧妙利用


     首先题意是告诉你要进行m次区间赋最值操作,要求你求出每一个值最后的大小,这题的难点在于查询m的次数是非常多的,高达1e8,所以你想用线段树边修改边查询是不可能的,(因为是随机出的数据,所以有一些剪枝被卡过去了,我女朋友就是这么过的,好气啊!!!)所以这个题用了我觉得很少见的一类数据结构ST表,ST的特征是可以用ologn的时间内建表,然后每次查询都是o(1)的,所以就是很适合这道题的特点了,因为这道题目也是有着多查询,和求最值的,所以我们使用了反着建立ST表的方法去实现这个东西,也是类似于dp的思想,上层是一个区间最大值,但是在dp的过程中,能把取最大值的路径合并一下,并使它的影响依然可以覆盖它的区间,这样逆序建立ST表可以处理区间最大值问题,并快速离线查询。

      待更新:ST表的其他妙用(暂时还没想到这东西除了快速求最值外还有什么用,其实就是快速把可以混淆影响的区间结果以dp的方式传播到下一层吧)

    #include<iostream>
    #include<cstring>
    #include <string>
    #include<algorithm>
    #include<map>
    #include<stack>
    #include<queue>
    #include <math.h>
    #include<vector>
    #define lson rt<<1
    #define rson rt<<1|1
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+20;
    const int mod=1e9+7;
    typedef unsigned long long ull;
    typedef long long ll;
    const double pai=acos(-1),eps=1e-8;
    int k,len;
    unsigned int X,Y,Z;
    int st[maxn][20];
    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 logg[maxn];
    int main()
    {
        int T=1,num=0;
        for(int i=1;i<maxn;i++)
        {
            if(i<T*2)
                logg[i]=num;
            else{
                T=T*2;
                num++;
                logg[i]=num;
            }
        }
        cin>>T;
        
        while(T--)
        {
            
            int n,m;
            scanf("%d%d%d%d%d",&n,&m,&X,&Y,&Z);
    //        cin>>n>>m>>X>>Y>>Z;
            for(int i=30;i>=0;i--)
            {
                for(int j=1;j<=n;j++)
                    st[j][i]=0;
            }
            for(int i=0;i<m;i++)
            {
                unsigned int a=rng61()%n+1,b=rng61()%n+1,c=rng61()%(1<<30);
                if(a>b)
                    swap(a, b);
                int d=logg[(b-a+1)];
                st[a][d]=max(st[a][d],(int)c);
                st[b-(1<<d)+1][d]=max(st[b-(1<<d)+1][d],(int)c);
            }
            
            for(int i=logg[n+1];i>0;i--)
            {
                for(int j=1;j<=n;j++)
                {
                    
                    int j2=j+(1<<(i-1));
                    
                    if(j2<=n)
                        st[j2][i-1]=max(st[j2][i-1],st[j][i]);
                    st[j][i-1]=max(st[j][i],st[j][i-1]);
                }
            }
            ll ans=0;
            for(int i=1;i<=n;i++)
                ans^=(i*1LL)*st[i][0];
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    codevs 1432 总数统计
    codevs3500 快速幂入门题解
    #163. 【清华集训2015】新式计算机
    2989:糖果
    191:钉子和小球
    java 删除所有HTML工具类
    DateTools时间插件
    新的开始
    springBoot---端口,路径数据配置
    springBoot---多个配置文件读取
  • 原文地址:https://www.cnblogs.com/King-of-Dark/p/11626138.html
Copyright © 2020-2023  润新知