2018 Multi-University Training Contest 5 1007:Glad You Came(线段树暴力)

题目大意:

给你n个初始化为0的数,m次操作,

每次操作将 l r 区间内的所有小于val的更新为val。

最后查询所有数的异或和。

解题思路:

刚上来队友给我讲了题意后第一反应,这不是个线段树区间更新裸题嘛。但后来一想如果是这样不可能过的人这么少。就强行自己干掉了线段树写法,yy了另一种mlogm的写法,真的智障,T了两发以后发现线段树的复杂度貌似是mlogn的就滚去写线段树了结果1A。中间还尝试过只取最大的10000个val值的写法hhhh ,不过对拍出了一组错误数据就没敢交。。。

最后发现题解的解法真的巧妙,运用了ST表的知识,不过我等凡人就只能搞一搞线段树的暴力写法。

Ac代码:

#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
const int MAX=1e5+10;
const int MOD=1e9+7;
const double PI=acos(-1.0);
typedef long long ll;

ll ans;
struct node
{
    int l,r,mid;    //维护区间最小值
    ll val;
}t[MAX<<2];

unsigned X,Y,Z,W;
unsigned f()
{
    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;
}
void pushup(int rt)
{
    t[rt].val=min(t[lson].val,t[rson].val);
}
void pushdown(int rt)
{
    if(t[rt].val)
    {
        t[lson].val=max(t[lson].val,t[rt].val); //pushdown要取较大值
        t[rson].val=max(t[rson].val,t[rt].val);
        t[rt].val=0;
    }
}
void build(int l,int r,int rt)
{
    int mid=(l+r)>>1;
    t[rt].l=l,t[rt].r=r,t[rt].mid=mid;
    t[rt].val=0;
    if(l==r)
        return ;
    build(l,mid,lson);
    build(mid+1,r,rson);
    pushup(rt);
}
void update(int l,int r,ll val,int rt)
{
    if(t[rt].val>=val) return ; //这一步的剪枝很关键
    if(l<=t[rt].l&&t[rt].r<=r)
    {
        if(t[rt].val<=val) t[rt].val=val; //符合要求就更新
        return ;
    }
    pushdown(rt);
    if(l<=t[rt].mid) update(l,r,val,lson);
    if(r>t[rt].mid) update(l,r,val,rson);
    pushup(rt);
}
void query(int l,int r,int rt)
{
    if(t[rt].l==t[rt].r)
    {
        ans=ans^(t[rt].val*t[rt].l); //求答案
        return ;
    }
    pushdown(rt);
    query(l,r,lson);
    query(l,r,rson);
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        cin>>X>>Y>>Z;
        build(1,n,1);
        int l,r; ll val;
        for(int i=1;i<=m;i++)
        {
            ll x=f();
            ll y=f();
            l=min(x%n+1,y%n+1);
            r=max(x%n+1,y%n+1);
            val=f()%(1<<30);
            update(l,r,val,1);
        }
        ans=0;
        query(1,n,1);
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/f2935552941/article/details/81460692
今日推荐