线段树模板

线段树

  • 维护最长区间长度(HDU - 1540)
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 50005;
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
int n;
struct node
{
    int lmax, rmax, maxx;
    node(int _l,int _r,int _m):lmax(_l),rmax(_r),maxx(_m){}
    node(){}
}nodes[maxn << 2];
void build(int l, int r, int rt)
{
    nodes[rt] = node(r - l + 1, r - l + 1, r - l+1);
    if (l == r)return;
    int m = l + r >> 1;
    build(ls);
    build(rs);
}

void pushup(int rt,int ln,int rn)
{
    nodes[rt] = node(nodes[rt << 1].lmax, nodes[rt << 1 | 1].rmax, 0);
    nodes[rt].maxx = max(nodes[rt << 1].maxx, nodes[rt << 1 | 1].maxx);
    nodes[rt].maxx = max(nodes[rt].maxx, nodes[rt << 1].rmax + nodes[rt << 1 | 1].lmax);
    if (nodes[rt << 1].lmax == ln)
        nodes[rt].lmax = ln + nodes[rt << 1 | 1].lmax;
    if (nodes[rt << 1 | 1].rmax == rn)
        nodes[rt].rmax = rn + nodes[rt << 1].rmax;

}

void update(int L,int C, int l, int r, int rt)
{
    if (l == r)
    {
        if (C)
            nodes[rt] = node(1, 1, 1);
        else
            nodes[rt] = node(0, 0, 0);
        return;
    }
    int m = l + r >> 1;
    if (L <= m)
        update(L, C, ls);
    else
        update(L, C, rs);
    pushup(rt,m-l+1,r-m);
}

int query(int L, int l, int r, int rt)
{
    if (l == r || nodes[rt].maxx == r - l + 1 || nodes[rt].maxx == 0)
        return nodes[rt].maxx;
    int m = l + r >> 1;
    if (L <= m)
    {
        if (L >= m - nodes[rt << 1].rmax + 1)
            return query(L, ls) + query(m + 1, rs);
        else
            return query(L, ls);
    }
    else
    {
        if (L <= m+1 + nodes[rt << 1 | 1].lmax-1)
            return query(L, rs) + query(m, ls);
        else
            return query(L, rs);
    }
}


int main()
{
    int n, m;
    while (~scanf("%d %d", &n, &m))
    {
        build(1, n, 1);
        char s[3];
        int x;
        int stack[50005], tot = 0;
        for (int i = 1;i <= m;i++)
        {
            scanf("%s", s);
            if (s[0] == 'D')
            {
                scanf("%d", &x);
                stack[++tot] = x;
                update(x, 0, 1, n, 1);
            }
            else if (s[0] == 'Q')
            {
                scanf("%d", &x);
                printf("%d\n", query(x, 1, n, 1));
            }
            else
            {
                int tmp = stack[tot--];
                update(tmp, 1, 1, n, 1);
            }
        }
    }
    return 0;
}
  • 扫描线求面积(HDU - 1542)
#include<iostream>
#include<algorithm>
using namespace std;
const int maxx = 100005;
const int maxn = 105;
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
struct line
{
    double l, r, h;
    int flag;
    line(double _l,double _r,double _h,int _f):l(_l),r(_r),h(_h),flag(_f){}
    line(){}
    bool operator<(const line &b)const
    {
        return h < b.h;
    }
}lines[maxn * 2];
double X[maxn * 2];
struct node
{
    int l, r;
    double len;
    int cnt;
    node(int _l, int _r, double _len, int _c) :l(_l), r(_r), len(_len), cnt(_c){}
    node(){}
}nodes[maxn << 3];
void build(int l, int r, int rt)
{
    nodes[rt] = node(l, r, 0.0, 0);
    if (l == r)return;
    int m = l + r >> 1;
    build(ls);
    build(rs);
}

void pushup(int rt)
{
    int lidx = nodes[rt].l, ridx = nodes[rt].r+1;
    if (nodes[rt].cnt)
        nodes[rt].len = X[ridx] - X[lidx];
    else if (nodes[rt].l == nodes[rt].r)
        nodes[rt].len = 0;
    else
        nodes[rt].len = nodes[rt << 1].len + nodes[rt << 1 | 1].len;
}

void update(int L, int R, int C, int l, int r,int rt)
{
    if (L <= l&&r <= R)
    {
        nodes[rt].cnt += C;
        pushup(rt);
        return;
    }
    int m = l + r >> 1;
    if (L <= m)update(L, R, C, ls);
    if (R > m)update(L, R, C, rs);
    pushup(rt);
}


int main()
{
    int n;
    int cas = 1;
    while (~scanf("%d",&n)&&n)
    {
        double x1, y1, x2, y2;
        int num = 0;
        int xnum = 0;
        for (int i = 1;i <= n;i++)
        {
            scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
            lines[num++] = line(x1, x2, y1, 1);
            lines[num++] = line(x1, x2, y2, -1);
            X[xnum++] = x1;
            X[xnum++] = x2;
        }
        sort(lines, lines + num);
        sort(X, X + xnum);
        xnum = unique(X, X + xnum)-X;
        build(0, xnum - 1, 1);
        double ans = 0;
        for (int i = 0;i < num-1;i++)
        {
            int lidx = lower_bound(X, X + xnum, lines[i].l) - X;
            int ridx = lower_bound(X, X + xnum, lines[i].r) - X;
            ridx--;
            update(lidx, ridx, lines[i].flag, 0, xnum - 1, 1);
            ans += nodes[1].len*(lines[i + 1].h - lines[i].h);
        }
        printf("Test case #%d\nTotal explored area: %.2f\n", cas++, ans);
        puts("");
    }

    return 0;
}

二维线段树

  • 单点修改,区间查询极值问题(2013长春区域赛G题)
#include<iostream>
#include<algorithm>

using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAXN 805   ///大小
struct seg   /// 单点修改,区间查询极值模板
{
    int xL, xR, yL, yR, val;       /// 查询时xL,xR,yL,yR为边界,修改时(xL,yL)为修改点val为值
    int maxv, minv;
    int Max[MAXN << 2][MAXN << 2], Min[MAXN << 2][MAXN << 2];
    int N, mat[MAXN][MAXN];
    void init()
    {
        maxv = -(1 << 30);
        minv = 1 << 30;
    }
    void PushUp(int xrt, int rt)
    {
        Max[xrt][rt] = max(Max[xrt][rt << 1], Max[xrt][rt << 1 | 1]);
        Min[xrt][rt] = min(Min[xrt][rt << 1], Min[xrt][rt << 1 | 1]);
    }
    void BuildY(int xrt, int x, int l, int r, int rt)//x=-1的时候相当于BuildX的pushup函数,等于其他的就相当于初始化.同理后面的UpdateY也是一样的道理。
    {
        int m;
        if (l == r)
        {
            if (x != -1)Max[xrt][rt] = Min[xrt][rt] = mat[x][l];
            else
            {
                Max[xrt][rt] = max(Max[xrt << 1][rt], Max[xrt << 1 | 1][rt]);
                Min[xrt][rt] = min(Min[xrt << 1][rt], Min[xrt << 1 | 1][rt]);
            }
            return;
        }
        m = l + r >> 1;
        BuildY(xrt, x, lson);
        BuildY(xrt, x, rson);
        PushUp(xrt, rt);
    }

    void BuildX(int l, int r, int rt)
    {
        int m;
        if (l == r)
        {
            BuildY(rt, l, 1, N, 1);
            return;
        }
        m = l + r >> 1;
        BuildX(lson);
        BuildX(rson);
        BuildY(rt, -1, 1, N, 1);
    }
    void UpdateY(int xrt, int x, int l, int r, int rt)
    {
        int m;
        if (l == r)
        {
            if (x != -1)Max[xrt][rt] = Min[xrt][rt] = val;
            else
            {
                Max[xrt][rt] = max(Max[xrt << 1][rt], Max[xrt << 1 | 1][rt]);
                Min[xrt][rt] = min(Min[xrt << 1][rt], Min[xrt << 1 | 1][rt]);
            }
            return;
        }
        m = (l + r) >> 1;
        if (yL <= m)UpdateY(xrt, x, lson);
        else UpdateY(xrt, x, rson);
        PushUp(xrt, rt);
    }
    void UpdateX(int l, int r, int rt)
    {
        int m;
        if (l == r)
        {
            UpdateY(rt, l, 1, N, 1);
            return;
        }
        m = (l + r) >> 1;
        if (xL <= m)UpdateX(lson);
        else UpdateX(rson);
        UpdateY(rt, -1, 1, N, 1);
    }
    void QueryY(int xrt, int l, int r, int rt)
    {
        int m;
        if (yL <= l&&yR >= r)
        {
            minv = min(minv, Min[xrt][rt]);
            maxv = max(maxv, Max[xrt][rt]);
            return;
        }
        m = (l + r) >> 1;
        if (yL <= m)QueryY(xrt, lson);
        if (yR>m)QueryY(xrt, rson);
    }
    void QueryX(int l, int r, int rt)
    {
        int m;
        if (xL <= l&&xR >= r)
        {
            QueryY(rt, 1, N, 1);
            return;
        }
        m = (l + r) >> 1;
        if (xL <= m)QueryX(lson);
        if (xR>m)QueryX(rson);
    }
}Seg;
int main()
{
    int T;
    scanf("%d", &T);
    for (int cas = 1;cas <= T;cas++)
    {
        scanf("%d", &Seg.N);
        for (int i = 1;i <= Seg.N;i++)
            for (int j = 1;j <= Seg.N;j++)
                scanf("%d", &Seg.mat[i][j]);
        Seg.BuildX(1, Seg.N, 1);
        int Q;
        scanf("%d", &Q);
        printf("Case #%d:\n", cas);
        int L, x, y;
        while (Q--)
        {
            scanf("%d %d %d", &x, &y, &L);
            int length = (L - 1) / 2;
            Seg.xL = max(1, x - length);
            Seg.xR = min(Seg.N, x + length);
            Seg.yL = max(1, y - length);
            Seg.yR = min(Seg.N, y + length);
            Seg.init();
            Seg.QueryX(1, Seg.N, 1);
            int themax = Seg.maxv;
            int themin = Seg.minv;
            printf("%d\n", (themax + themin) / 2);
            Seg.val = (themax + themin) / 2;
            Seg.xL = x;
            Seg.yL = y;
            Seg.UpdateX(1, Seg.N, 1);
        }
    }
}
资源下载链接为: https://pan.quark.cn/s/140386800631 通用大模型文本分类实践的基本原理是,借助大模型自身较强的理解和推理能力,在使用时需在prompt中明确分类任务目标,并详细解释每个类目概念,尤其要突出类目间的差别。 结合in-context learning思想,有效的prompt应包含分类任务介绍及细节、类目概念解释、每个类目对应的例子和待分类文本。但实际应用中,类目和样本较多易导致prompt过长,影响大模型推理效果,因此可先通过向量检索缩小范围,再由大模型做最终决策。 具体方案为:离线时提前配置好每个类目的概念及对应样本;在线时先对给定query进行向量召回,再将召回结果交给大模型决策。 该方法不更新任何模型参数,直接使用开源模型参数。其架构参考GPT-RE并结合相关实践改写,加入上下文学习以提高准确度,还使用BGE作为向量模型,K-BERT提取文本关键词,拼接召回的相似例子作为上下文输入大模型。 代码实现上,大模型用Qwen2-7B-Instruct,Embedding采用bge-base-zh-v1.5,向量库选择milvus。分类主函数的作用是在向量库中召回相似案例,拼接prompt后输入大模型。 结果方面,使用ICL时accuracy达0.94,比bert文本分类的0.98低0.04,错误类别6个,处理时添加“家居”类别,影响不大;不使用ICL时accuracy为0.88,错误58项,可能与未修改prompt有关。 优点是无需训练即可有较好结果,例子优质、类目界限清晰时效果更佳,适合围绕通用大模型api打造工具;缺点是上限不高,仅针对一个分类任务部署大模型不划算,推理速度慢,icl的token使用多,用收费api会有额外开销。 后续可优化的点是利用key-bert提取的关键词,因为核心词语有时比语意更重要。 参考资料包括
内容概要:本文详细介绍了哈希表及其相关概念和技术细节,包括哈希表的引入、哈希函数的设计、冲突处理机制、字符串哈希的基础、哈希错误率分析以及哈希的改进与应用。哈希表作为一种高效的数据结构,通过键值对存储数据,能够快速定位和检索。文中讨论了整数键值和字符串键值的哈希方法,特别是字符串哈希中的多项式哈希及其优化方法,如双哈希和子串哈希的快速计算。此外,还探讨了常见的冲突处理方法——拉链法和闭散列法,并提供了C++实现示例。最后,文章列举了哈希在字符串匹配、最长回文子串、最长公共子字符串等问题中的具体应用。 适合人群:计算机科学专业的学生、算法竞赛选手以及有一定编程基础并对数据结构和算法感兴趣的开发者。 使用场景及目标:①理解哈希表的工作原理及其在各种编程任务中的应用;②掌握哈希函数的设计原则,包括如何选择合适的模数和基数;③学会处理哈希冲突的方法,如拉链法和闭散列法;④了解并能运用字符串哈希解决实际问题,如字符串匹配、回文检测等。 阅读建议:由于哈希涉及较多数学知识和编程技巧,建议读者先熟悉基本的数据结构和算法理论,再结合代码实例进行深入理解。同时,在实践中不断尝试不同的哈希策略,对比性能差异,从而更好地掌握哈希技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值