主席树

 主席树


好神的数据结构,不过挺好写的。。

POJ 2104 K-th number

题目大意:
     对一静态序列,每次询问[l,r]中第k大d

主席树模板题

贴代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define M 100010
using namespace std;


struct Node{
    int l,r,s;
}a[M*50];

int id[M],d[M],cnt,key;
void update(int l,int r,int &pos)
{
    a[++cnt]=a[pos];
    pos=cnt;
    ++a[pos].s;
    if(l==r)
    return ;
    int m=(l+r)/2;
    if(key<=m)
    update(l,m,a[pos].l);
    else
    update(m+1,r,a[pos].r);
}

int query(int l,int r,int x,int y,int k)
{
    if(l==r)
    return l;
    int mid=(l+r)/2,s=a[a[y].l].s-a[a[x].l].s;
    if(k<=s)
    return query(l,mid,a[x].l,a[y].l,k);
    else
    return query(mid+1,r,a[x].r,a[y].r,k-s);
}
bool cmp(int x,int y)
{
    return d[x]<d[y];

}
int n,m;
int b[M];
int root[M];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    scanf("%d",&d[i]),id[i]=i;
    sort(id+1,id+n+1,cmp);
    for(int i=1;i<=n;i++)
    b[id[i]]=i;
    for(int i=1;i<=n;i++)
    {
        root[i]=root[i-1];
        key=b[i];
        update(1,n,root[i]);
    }
    int x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&key);
        int td=query(1,n,root[x-1],root[y],key);
        printf("%d\n",d[id[td]]);

    }
    return 0;
}


HDU 4417 Super Mario

题目大意:

对于一静态序列,询问[l,r]中小于x的个数

这题有树状数组解法,不过我用二分+主席树过了,
(跑得也很快,BIT 200+ms   二分+主席树 500+ms

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define M  100010

using namespace std;

int d[M],b[M],id[M],root[M],cnt,key,T,n,m;
struct Node{

    int l,r,s;
}a[M*30];


bool cmp (int x,int y)
{
    return d[x]<d[y];
}
void update(int &t,int l,int r)
{
    a[++cnt]=a[t];
    t=cnt;
    ++a[t].s;
    if(l==r)
        return ;
    int mid=(l+r)/2;
    if(key<=mid)
        update(a[t].l,l,mid);
    else
        update(a[t].r,mid+1,r);
}
int query(int l,int r,int x,int y,int k)
{
    if(l==r)
        return l;
    int mid=(l+r)/2,s=a[a[y].l].s-a[a[x].l].s;
    if(k<=s)
    return query(l,mid,a[x].l,a[y].l,k);
    else
    return query(mid+1,r,a[x].r,a[y].r,k-s);
}


int main()
{
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        scanf("%d%d",&n,&m);
        printf("Case %d:\n",cas);
        for(int i=1;i<=n;i++)
            scanf("%d",&d[i]),id[i]=i;
        sort(id+1,id+n+1,cmp);
        for(int i=1;i<=n;i++)
            b[id[i]]=i;
        for(int i=1;i<=n;i++)
        {
            root[i]=root[i-1];
            key=b[i];
            update(root[i],1,n);
        }
        for(int i=1,x,y;i<=m;i++)
        {
            scanf("%d%d%d",&x,&y,&key);
            x++,y++;
            if(d[id[query(1,n,root[x-1],root[y],y-x+1)]]<=key)
            {
                printf("%d\n",y-x+1);

            }
            else
                if(d[id[query(1,n,root[x-1],root[y],1)]]>key)
            {

                printf("0\n");
            }
            else
            {
                int l=0,r=y-x+1;
                int ans=0,mid;
                while(l<=r)
                {
                    int mid=(l+r)/2;
                    if(d[id[query(1,n,root[x-1],root[y],mid)]]<=key)
                        l=mid+1,ans=mid;
                    else
                        r=mid-1;
                }
                printf("%d\n",ans);
            }
        }
    }
    return 0;


}


SPOJ COT Count on a tree

s=s(lson[u])+s(lson[v])-2*s(lson[lca])
记住如果lca 在[l,mid] 中 s要+1

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define M 100005

using namespace std;

int g[M];
struct Edge
{
    int nxt,v;
} e[M*2];

struct Node
{
    int l,r,s;

} a[M*20];
vector<pair<int ,int > > q[M];
int cnt,num,key,n,m;
int p[M],fa[M],id[M],d[M],b[M],root[M];
int from[M],to[M],val[M];
void add(int u,int v)
{
    e[++cnt].nxt=g[u],e[cnt].v=v,g[u]=cnt;
    e[++cnt].nxt=g[v],e[cnt].v=u,g[v]=cnt;
}

void update(int &t,int l,int r)
{
    a[++num]=a[t];
    t=num;
    ++a[t].s;
    if(l==r)
        return ;
    int mid=(l+r)/2;
    if(key<=mid)
        update(a[t].l,l,mid);
    else
        update(a[t].r,mid+1,r);
}

int ifind(int x)
{
    return p[x] == x  ?  x : p[x]=ifind(p[x]);
}
bool vis[M];
int lca[M];

void dfs(int x)
{
   // cout<<x<<endl;
    p[x]=x;
    key=b[x];
    root[x]=root[fa[x]];
    update(root[x],1,n);
    for(int i=g[x]; i; i=e[i].nxt)
        if(e[i].v!=fa[x])
        {
            //cout<<e[i].v<<endl;
            fa[e[i].v]=x;
            dfs(e[i].v);
            p[e[i].v]=x;
        }
    vis[x]=1;
    int t=q[x].size();
    for(int i=0; i<t; ++i)
        if(vis[q[x][i].first])
        {
            lca[q[x][i].second]=ifind(q[x][i].first);
        }
}

bool cmp(int x,int y)
{
    return d[x]<d[y];


}

int getans(int l,int r,int x,int y,int f,int k)
{
    if(l==r)
        return l;
    int mid=(l+r)/2,s=a[a[x].l].s+a[a[y].l].s-(a[a[f].l].s<<1);
    if(b[key]>=l && b[key]<=mid)
        ++s;
    if(k<=s)
        return getans(l,mid,a[x].l,a[y].l,a[f].l,k);
    else
        return getans(mid+1,r,a[x].r,a[y].r,a[f].r,k-s);
}


int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
        scanf("%d",&d[i]),id[i]=i;
    sort(id+1,id+n+1,cmp);
    for(int i=1; i<=n; i++)
        b[id[i]]=i;
    for(int i=1,x,y; i<n; i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
    }
    for(int i=1; i<=m; ++i)
    {
        scanf("%d%d%d",&from[i],&to[i],&val[i]);
        q[from[i]].push_back(pair<int, int> (to[i], i));
        q[to[i]].push_back(pair<int, int> (from[i], i));
    }
    dfs(1);
    for(int i=1; i<=m; ++i)
    {
        if(from[i]==to[i])
        {
            printf("%d\n", d[from[i]]);
            continue;
        }
        key=lca[i];
        printf("%d\n", d[id[getans(1, n, root[from[i]], root[to[i]], root[key], val[i])]]); //被root[ff]坑了一早上,写成了ff。唉
    }
    return 0;
}




本课题设计了一种利用Matlab平台开发的植物叶片健康状态识别方案,重点融合了色彩与纹理双重特征以实现对叶片病害的自动化判别。该系统构建了直观的图形操作界面,便于用户提交叶片影像并快速获得分析结论。Matlab作为具备高效数值计算与数据处理能力的工具,在图像分析与模式分类领域应用广泛,本项目正是借助其功能解决农业病害监测的实际问题。 在色彩特征分析方面,叶片影像的颜色分布常与其生理状态密切相关。通常,健康的叶片呈现绿色,而出现黄化、褐变等异常色彩往往指示病害或虫害的发生。Matlab提供了一系列图像处理函数,例如可通过色彩空间转换与直方图统计来量化颜色属性。通过计算各颜色通道的统计参数(如均值、标准差及主成分等),能够提取具有判别力的色彩特征,从而为不同病害类别的区分提供依据。 纹理特征则用于描述叶片表面的微观结构与形态变化,如病斑、皱缩或裂纹等。Matlab中的灰度共生矩阵计算函数可用于提取对比度、均匀性、相关性等纹理指标。此外,局部二值模式与Gabor滤波等方法也能从多尺度刻画纹理细节,进一步增强病害识别的鲁棒性。 系统的人机交互界面基于Matlab的图形用户界面开发环境实现。用户可通过该界面上传待检图像,系统将自动执行图像预处理、特征抽取与分类判断。采用的分类模型包括支持向量机、决策树等机器学习方法,通过对已标注样本的训练,模型能够依据新图像的特征向量预测其所属的病害类别。 此类课题设计有助于深化对Matlab编程、图像处理技术与模式识别原理的理解。通过完整实现从特征提取到分类决策的流程,学生能够将理论知识与实际应用相结合,提升解决复杂工程问题的能力。总体而言,该叶片病害检测系统涵盖了图像分析、特征融合、分类算法及界面开发等多个技术环节,为学习与掌握基于Matlab的智能检测技术提供了综合性实践案例。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值