Skip to content

泉州一中信息学Blog

信息学奥赛技术分享博客

  • 登录
  • 小学oj
  • 中学oj
  • 测试页面1
  • Toggle search form

HLOJ-DAY 6

Posted on 2024年7月8日2024年7月9日 By 张, 高畅 HLOJ-DAY 6无评论

什么已经第六天了!

什么今天还是数据结构!

[C]

原题

首先在这之前我们要了解笛卡尔树

(光速吟唱)

笛卡尔树是每一个节点由二元组组成的一棵树,其中前一维满足BST的性质,后一维满足Heap的性质。

而神奇的Treap其实就是前一维随机的一种笛卡尔树。

(吟唱完毕)

这一题就只需要 O(n) 的把笛卡尔树建出来,然后 dfs 访问就可以了。

#include
using namespace std;
const int N=1e5+5;
int n,p[N],stk[N],top;
int ls[N],rs[N];
int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch57)
    {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>=48&&ch<=57)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    return x*f;
}
void dfs(int u)
{
    if(!u)return;
    printf("%d ",u);
    dfs(ls[u]);
    dfs(rs[u]);
}
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        int x=read();
        p[x]=i;
    }
    for(int i=1;i0&&p[stk[k]]>p[i])k--;
        if(k)rs[stk[k]]=i;
        if(k<top)ls[i]=stk[k+1];
        stk[top=++k]=i;
    }
    dfs(stk[1]);
    return 0;
}

[F]

原题

使用可持久化线段树维护区间的和/左边最大子段和/右边最大子段和。
注意合并时的细节。

#include
using namespace std;
const int N=20005;
int n;
paira[N];
struct node
{
    int sum,lmax,rmax;
    int ls,rs;
}tr[N<>1;
    build(tr[u].ls,l,mid);
    build(tr[u].rs,mid+1,r);
    pushup(u);
}
void modify(int root,int &u,int l,int r,int p)
{
    tr[u=++tot]=tr[root];
    if(l==r)
    {
        tr[u]={-1,-1,-1};
        return; 
    }
    int mid=l+r>>1;
    if(p<=mid)modify(tr[root].ls,tr[u].ls,l,mid,p);
    else modify(tr[root].rs,tr[u].rs,mid+1,r,p);
    pushup(u);
}
int query_sum(int u,int l,int r,int L,int R)
{
    if(L<=l&&r>1;
    if(Rmid)return query_sum(tr[u].rs,mid+1,r,L,R);
    else return query_sum(tr[u].ls,l,mid,L,mid)+query_sum(tr[u].rs,mid+1,r,mid+1,R);
}
int query_lmax(int u,int l,int r,int L,int R)
{
    if(L<=l&&r>1;
    if(Rmid)return query_lmax(tr[u].rs,mid+1,r,L,R);
    else return max(query_lmax(tr[u].ls,l,mid,L,mid),query_lmax(tr[u].rs,mid+1,r,mid+1,R)+query_sum(tr[u].ls,l,mid,L,mid));
}
int query_rmax(int u,int l,int r,int L,int R)
{
    if(L<=l&&r>1;
    if(Rmid)return query_rmax(tr[u].rs,mid+1,r,L,R);
    else return max(query_rmax(tr[u].rs,mid+1,r,mid+1,R),query_rmax(tr[u].ls,l,mid,L,mid)+query_sum(tr[u].rs,mid+1,r,mid+1,R));
}
int check(int a,int b,int c,int d,int x)
{
    int res=0;
    if(b+1=0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].first);
        a[i].second=i;
    }
    sort(a+1,a+n+1);
    build(root[1],1,n);
    for(int i=2;i<=n+1;i++)modify(root[i-1],root[i],1,n,a[i-1].second);
    int q;
    scanf("%d",&q);
    int x=0;
    while(q--)
    {
        int b[4];
        for(int i=0;i<4;i++)
        {
            scanf("%d",&b[i]);
            b[i]=(b[i]+x)%n+1;
        }
        sort(b,b+4);
        int l=1,r=n;
        while(l>1;
            if(check(b[0],b[1],b[2],b[3],mid))l=mid;
            else r=mid-1;
        }
        printf("%d\n",x=a[l].first);
    }
    return 0;
}

[H]

原题
太有意思了。
其实可以不用离散化的。
首先判断出现次数为奇数次,我们考虑将每一个数附一个unsigned long long 内的一个随机的权值
因为unsigned long long的范围是 [0,2^{64}-1] 的,所以使用异或hash冲突的概率是足够小的。
然后考虑把这个东西拖到主席树内维护。
每一次询问实际上就是询问$root{l-1}与root{r}$的版本,我们只需要在主席树上二分就可以了。

#include<bits/stdc++.h>
#include<random>
using namespace std;
const int N=2e5+5,INF=2e9+5;
typedef long long LL;
typedef unsigned long long ULL;
LL n,m,tot,root[N];
mt19937 rd(random_device{}());
unordered_map<LL,ULL>mp;
struct node
{
    LL ls,rs;
    ULL w;
}tr[N<<5];
void pushup(int u){tr[u].w=tr[tr[u].ls].w^tr[tr[u].rs].w;}
void modify(LL root,LL &u,LL l,LL r,LL x,ULL v)
{
    tr[u=++tot]=tr[root];
    if(l==r)
    {
        tr[u].w^=v;
        return;
    }
    LL mid=l+r>>1;
    if(x<=mid)modify(tr[root].ls,tr[u].ls,l,mid,x,v);
    else modify(tr[root].rs,tr[u].rs,mid+1,r,x,v);
    pushup(u);
}
LL query(LL u1,LL u2,LL l,LL r)
{
    if(l==r)return l;
    ULL x=tr[tr[u1].ls].w^tr[tr[u2].ls].w;
    LL mid=l+r>>1;
    if(x)return query(tr[u1].ls,tr[u2].ls,l,mid);
    else return query(tr[u1].rs,tr[u2].rs,mid+1,r);
}
int main()
{
    scanf("%lld",&n);
    for(LL i=1,x;i<=n;i++)
    {
        scanf("%lld",&x);
        if(!mp[x])mp[x]=rd();
        modify(root[i-1],root[i],0,INF,x,mp[x]);
    }
    LL lastans=0;
    scanf("%lld",&m);
    while(m--)
    {
        LL l,r;
        scanf("%lld%lld",&l,&r);
        l^=lastans;
        r^=lastans;
        lastans=query(root[l-1],root[r],0,INF);
        if(lastans==INF)lastans=0;
        printf("%lld\n",lastans);
    }
    return 0;
}
训练日志

文章导航

Previous Post: HLOJ-DAY 5
Next Post: F参考代码

发表回复 取消回复

要发表评论,您必须先登录。

2025年 6月
一 二 三 四 五 六 日
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« 2月    

2024常州 Class Classic OI Problems Contest cqr的长乐集训2023 CZYZ LOC New Game NOI NOIP Password Protected PM_PK Preview Problems Retrospect Selfmade Qusetion STL The end Training Uneasy Problem 蒟蒻 通报

  • 训练日志
  • 链表
  • 入门
  • 模拟
  • dfs序
  • 并查集
  • spfa
  • 最小割
  • 矩阵树定理
  • 仙人掌
  • BSGS
  • 凸包
  • 回文自动机
  • 递推与动归
  • 堆
  • 莫队算法
  • ST表
  • Treap
  • 树套树
  • 可持久化线段树
  • 初赛
  • 搜索
  • 贪心
  • 深度优先搜索
  • 欧拉图
  • dijkstra
  • 费用流
  • 哈夫曼树
  • kruskual
  • 置换
  • 旋转卡壳
  • KMP
  • 区间动归
  • STL
  • 链表
  • 可并堆
  • sply
  • 主席树
  • 可持久化字典树
  • 算法
  • 动态规划
  • 构造
  • 广度优先搜索
  • 最短路
  • floyd
  • 最大流
  • 虚树
  • prim
  • 筛法
  • 半平面交
  • 字典树
  • 背包动归
  • 基础数据结构
  • 分块
  • 线段树
  • 替罪羊树
  • K-DTree
  • 图论
  • 二分法
  • 迭代搜索
  • 拓扑排序
  • 有上下界网络流
  • 生成树
  • 快速幂
  • 后缀数组
  • 树形动归
  • 哈希表
  • 中级数据结构
  • 平衡树
  • 可持久化数据结构
  • 数据结构
  • 三分法
  • 启发式搜索
  • 图的连通
  • 点分治
  • 博弈论
  • AC自动机
  • 状压动归
  • 单调栈
  • 树状数组
  • 高级数据结构
  • OI资料
  • 数学
  • 高精度
  • 差分约束
  • 树上倍增
  • 素数测试
  • 后缀自动机
  • 数位动归
  • 单调队列
  • 新闻
  • 几何
  • 随机化
  • 二分图染色
  • 树链剖分
  • 欧拉函数
  • manacher
  • 斜率优化
  • 离线处理
  • 信息学奥赛学长风采
  • 字符串
  • 二分图匹配
  • prufer编码
  • 卡特兰数
  • 密码学
  • 决策单调
  • 赛后总结
  • 其他
  • 2-SAT
  • 最近公共祖先
  • 矩阵乘法
  • 记忆化搜索
  • 网络流
  • Link cut tree
  • 排列组合
  • 树
  • 高斯消元
  • 乘法逆元
  • 容斥原理
  • 调和级数
  • 概率与期望
  • 模线性方程组
  • 莫比乌斯反演
  • 快速傅里叶变换
  • 扩展欧几里德
  • 最大公约数与最小公倍数

近期文章

  • DP杂题
  • 2025年2月13日模拟赛
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 3
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 2
  • HLOJ-TEST ROUND 4-T1/T2(构造)- 1

近期评论

归档

  • 2025年2月
  • 2025年1月
  • 2024年11月
  • 2024年10月
  • 2024年9月
  • 2024年8月
  • 2024年7月
  • 2024年3月
  • 2024年2月
  • 2024年1月
  • 2023年12月
  • 2023年11月
  • 2023年10月
  • 2023年9月
  • 2023年8月
  • 2023年7月
  • 2023年3月
  • 2023年2月
  • 2023年1月
  • 2022年12月

Copyright © 2025 泉州一中信息学Blog.

Powered by PressBook WordPress theme