HDU 6356 Glad You Came Problem 1007 杭电多校第五场
本文最后更新于 1167 天前,其中的信息可能已经有所发展或是发生改变。

内容纲要

题意

给定长为$n$的数组,初始值均为0
执行m个操作,每次操作的行为
如原题面

题解

很多人用线段树弄过去了,但是这个非常考验模板的水平,如果常数比较大这个方法就GG了

官方题解的解法说的不是很清楚,而根据官方标程的实现方式,实际上就是一个标准的RMQ逆向的过程。

首先对于RMQ 我们要学习什么是ST表。附录:ST表
然后我们在m次操作中,把一个区间分成两份:
令 $d$ 等于 $\left \lfloor \log_2(r – l + 1) \right \rfloor$,我们可以用两个操作 $(l, l + 2^d – 1, v)$ 和 $(r – 2^d + 1, r, v)$ 替换此操作。正如RMQ查询过程中把一个区间分成两份一样。(详见算法竞赛入门经典–训练指南P198)
求log的操作应该预处理出log表

然后我们反过来把最大值向长度为1的区间进行合并,这个过程是$\mathcal O(nlogn)$的


最后$\mathcal O(n)$扫一遍长度为0的区间即可。
初始化的过程可以在合并区间的过程进行。

这里有一个小小的优化:
v是要对$2^{30}$取模的,我们知道$2^{30}$用二进制表示只有一个1,后面都是0
因此我们可以用位运算代替模运算。
如模运算$8_{10} = 1000_{2}$ 等价于与运算 $7_{10} = 0111_{2}$

AC代码

#pragma GCC optimize("O3")

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <array>

using namespace std;
using ll = long long;
using LL = ll;
using un = unsigned;
const int maxn = 1e5 + 6, maxd = 17;
int T, n, m, mx, Log[maxn], a[maxd][maxn];
un X, Y, Z;

un rng61() {
    X ^= X << 11;
    X ^= X >> 4;
    X ^= X << 5;
    X ^= X >> 14;
    un tmp = X ^Y ^Z;
    X = Y;
    Y = Z;
    Z = tmp;
    return Z;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for (int i = 2; i < maxn; ++i)
        Log[i] = Log[i >> 1] + 1;
    cin >> T;
    while (T--) {
        cin >> n >> m >> X >> Y >> Z;
        for (mx = 0; 1 << mx <= n; ++mx);
        while (m--) {
            int L = rng61() % n + 1, R = rng61() % n + 1, v = rng61() & ((1 << 30) - 1);
            if (L > R)
                swap(L, R);
            int d = Log[R - L + 1];
            a[d][L] = max(a[d][L], v);
            a[d][R - (1 << d) + 1] = max(a[d][R - (1 << d) + 1], v);
        }
        for (int i = mx - 1; i > 0; --i)
            for (int j = 1; j + (1 << i) - 1 <= n; ++j) {
                a[i - 1][j] = max(a[i - 1][j], a[i][j]);
                a[i - 1][j + (1 << (i - 1))] = max(a[i - 1][j + (1 << (i - 1))], a[i][j]);
                a[i][j] = 0;
            }
        LL ans = 0;
        for (int i = 1; i <= n; ++i) {
            ans ^= (LL) i * a[0][i];
            a[0][i] = 0;
        }
        cout << ans << "\n";
    }
}

附线段树的写法 引用自https://blog.csdn.net/f2935552941/article/details/81460692

#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;
}

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇