首页 > 其他分享 >线段树查询i到j最长增加子串和序列

线段树查询i到j最长增加子串和序列

时间:2023-02-09 09:46:39浏览次数:54  
标签:子串 cout int 线段 查询 build ans 100 dp

基础篇

最长增加子数组 - 楠030416 - 博客园 (cnblogs.com)

增加线段树

子串

#include<bits/stdc++.h>
using namespace std;
//最长连续增加子串 
int a[100],dp[100],tree[100];

void build(int o, int l, int r)
{
    if(l == r)
    {
        tree[o] = dp[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(o << 1, l, mid);
    build(o << 1 | 1, mid + 1, r);
    tree[o] = max(tree[o << 1], tree[o << 1 | 1]);
}

int query(int o, int l, int r, int L, int R)
{
    if(L <= l && r <= R)return tree[o];
    int mid = (l + r) >> 1;
    int ans = 0;
    if(L <= mid)ans = max(ans, query(o << 1, l, mid, L, R));
    if(R > mid)ans = max(ans, query(o << 1 | 1, mid + 1, r, L, R));
    return ans;
}

int main()
{
    int n,m;//n数组元素个数,m问询次数 
    cin>>n>>m;
    
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        dp[i]=1;
    }
    
    for(int i=2;i<=n;i++)
    {
        if(a[i]>a[i-1])
        {
           dp[i]=dp[i-1]+1;
        }
        else
        dp[i]=1;
    }
    
    build(1,1,n); 
    
    cout<<"dp"<<endl;
    for(int i=1;i<=n;i++)
    cout<<dp[i]<<" ";
    
    cout<<"tree"<<endl;
    for(int i=1;i<2*n;i++)
    cout<<tree[i]<<" ";
    
    cout<<endl;
    for(int i=0;i<m;i++)
    {
        int l,r;
            cin>>l>>r;
            cout<<"结果"<<query(1,1,n,l,r)<<endl;
    } 
}

子序列

#include<bits/stdc++.h>
using namespace std;
//最长连续增加子序列 ,不一定连续 
int a[100],dp[100],tree[200],maxn=0;

void build(int o, int l, int r)
{
    if(l == r)
    {
        tree[o] = dp[l];
        return;
    }
    int mid = (l + r) >> 1;
    build(o << 1, l, mid);
    build(o << 1 | 1, mid + 1, r);
    tree[o] = max(tree[o << 1], tree[o << 1 | 1]);
}

int query(int o, int l, int r, int L, int R)
{
    if(L <= l && r <= R)return tree[o];
    int mid = (l + r) >> 1;
    int ans = 0;
    if(L <= mid)ans = max(ans, query(o << 1, l, mid, L, R));
    if(R > mid)ans = max(ans, query(o << 1 | 1, mid + 1, r, L, R));
    return ans;
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    int maxn=0;
    for(int i=1;i<=n;i++)
    {
           for(int j=1;j<i;j++)
           {
               int t=0; 
               t=dp[j];
               if(a[j]<a[i])
                   t++;
               if(t>dp[i])
                dp[i]=t;
        }
   }
    build(1,1,n); 
    
    cout<<"dp"<<endl;
    for(int i=1;i<=n;i++)
    cout<<dp[i]<<" ";
    cout<<endl;
    
    cout<<"tree"<<endl;
    for(int i=1;i<2*n;i++)
    cout<<tree[i]<<" ";
    cout<<endl;
    
    for(int i=0;i<m;i++)
    {
        int l,r;
        cin>>l>>r;
        cout<<"结果"<<query(1,1,n,l,r)<<endl;
    } 

}

 

标签:子串,cout,int,线段,查询,build,ans,100,dp
From: https://www.cnblogs.com/weinan030416/p/17104131.html

相关文章