2018HDU 多校6356 Glad You Came --- RMQ 反向ST表 (2018多校5)

待研究,标称做法,反向跑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;
}

猜你喜欢

转载自blog.csdn.net/axuhongbo/article/details/81783063
今日推荐