hdu 4339 Query

本文介绍了一道关于线段树的数据结构题目,通过单点更新实现区间查询,记录区间内首个不同元素位置。文章提供了完整的C++代码实现,包括线段树的建立、更新及查询操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.hdu.edu.cn/showproblem.php?pid=4339


这次多校我就出了这么个水题,伤心呀……

思路: 单点更新,线段树每个节点记录该区间从左向右第一个不一样的点的位置,这道题目的难点就是在于区间的合并的时候


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=1000100;

int d[maxn*4];
char s1[maxn],s2[maxn];

void build(int l,int r,int rt)
{
    if(l==r)
    {
        if(s1[l]==s2[r]) d[rt]=l;
        else d[rt]=-1;
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    if(d[rt<<1]==m) d[rt]=max(d[rt<<1],d[rt<<1|1]);
    else d[rt]=d[rt<<1];
}

void update(int id,int p,char cc,int l,int r,int rt)
{
    if(l==r)
    {
        if(id==1) s1[p]=cc;
        else s2[p]=cc;
        if(s1[l]==s2[r]) d[rt]=l;
        else d[rt]=-1;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m) update(id,p,cc,lson);
    else update(id,p,cc,rson);
    if(d[rt<<1]==m) d[rt]=max(d[rt<<1],d[rt<<1|1]);
    else d[rt]=d[rt<<1];
    //cout<<rt<<" "<<l<<" "<<r<<" "<<d[rt]<<endl;
}
int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r) return d[rt];
    int m=(l+r)>>1,ret1=-1,ret2=-1;
    if(R<=m) return query(L,R,lson);
    if(L>m)  return query(L,R,rson);
    ret1=query(L,m,lson);
    if(ret1==m) ret2=query(m+1,r,rson);
    if(ret1==m) return max(ret1,ret2);
    else return ret1;
}
int main()
{
    int ca,Q,id,p,Max,cas=1;
    char cc[4];
    scanf("%d",&ca);
    while(ca--)
    {
        scanf("%s %s",s1,s2);
        scanf("%d",&Q);
        int len1=strlen(s1),len2=strlen(s2);
        Max=min(len1,len2)-1;
        build(0,Max,1);
        printf("Case %d:\n",cas++);
        while(Q--)
        {
            scanf("%d",&id);
            if(id==1)
            {
                scanf("%d %d %s",&id,&p,cc);
                update(id,p,cc[0],0,Max,1);
            }
            else
            {
                scanf("%d",&p);
                int ans=query(p,Max,0,Max,1);
                if(ans==-1) printf("0\n");
                else printf("%d\n",ans-p+1);
            }
        }
    }
    return 0;
}


### HDU 6468 题目详解 HDU 6468 是一道涉及数据结构优化的经典问题。尽管具体的题目描述未提供,但从常见的 HDU 平台上的题目风格来看,这类问题通常围绕高效的数据处理展开。以下是针对可能的解法和分析。 #### 数据结构的选择 对于类似 HDU 6468 的问题,如果涉及到动态查询或修改操作,线段树、并查集或者二分查找可能是核心工具[^3]。例如,在某些场景下,我们需要快速找到满足条件的位置或将某个区间标记为已占用。这种需求可以通过维护一棵支持范围更新和单点查询的线段树来实现。 #### 线段树的应用 假设本题需要解决的是如何在高度受限的情况下分配公告牌位置,则可以借鉴 `hdu2795` 中提到的方法。通过构建一颗覆盖整个区域的高度线段树,每次尝试放置新广告时执行如下逻辑: 1. **寻找合适位置**:利用线段树查询功能定位第一个可用行号。 2. **更新状态信息**:一旦确定某一行可容纳当前广告,立即调整对应节点存储的最大剩余宽度值。 下面是伪代码表示上述过程: ```python def place_ad(tree, h, w): pos = query_first_available(tree, root=1, l=0, r=h-1, width=w) if pos != -1: update_width(tree, index=pos, delta=-w) return True return False def build_tree(h): ... def query_first_available(...): ... def update_width(...): ... ``` 其中函数定义需依据实际编码环境补充完整细节。 #### 时间复杂度考量 相比朴素做法 O()[^3] ,采用线段树后整体性能显著提升至接近于 O(n log n) 。这是因为每轮迭代仅需花费常数倍log级别开销完成必要计算即可得出结论。 --- ### 总结 综上所述,面对像 HDU 6468 这样的挑战性编程竞赛试题时,合理选用高级数据结构至关重要。无论是借助 Union-Find 实现集合间关系管理还是依靠 Segment Tree 达成高效区间接口访问目标,都体现了算法设计中的智慧结晶[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值