HDU 4991 线段树 Ordered Subsequence

https://vjudge.net/contest/246506#problem/D

最近在做一套线段树 | | 树状数组的题目,感觉题目不错,分享一下

A numeric sequence of a i is ordered if a 1<a 2<……<a N. Let the subsequence of the given numeric sequence (a 1, a 2,……, a N) be any sequence (a i1, a i2,……, a iK), where 1<=i 1<i 2 <……<i K<=N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, eg. (1, 7), (3, 4, 8) and many others. 

Your program, when given the numeric sequence, must find the number of its ordered subsequence with exact m numbers.

Input

Multi test cases. Each case contain two lines. The first line contains two integers n and m, n is the length of the sequence and m represent the size of the subsequence you need to find. The second line contains the elements of sequence - n integers in the range from 0 to 987654321 each. 
Process to the end of file. 
[Technical Specification] 
1<=n<=10000 
1<=m<=100

Output

For each case, output answer % 123456789.

Sample Input

3 2
1 1 2
7 3
1 7 3 5 9 4 8

Sample Output

2
12

然后又做到了一道没有解析的题目,打算搞一搞

这道题,带一点递推,至于怎么递推,还需要自己慢慢去找规律,先提示一下,可以开 maxn*100的二维数组,层层递推,也就相当于100颗线段树,用这一层的结果推下一层的。

然后就进行相关的操作,先查询上一层比它大的和,再更新,对于每一个点更新m次,m次递推。

算法复杂度是n*m*log(n)。

大家一定要有一些基础,因为我是做过一些类似的题了的。就是遇到一个值,就在这个值所对应的点插入线段树,最后查询的时候查询比这个值大的就行了(或者小的)

建议大家先从基础做起   POJ 2299 HDU 2838

然后再做这一题

下面自己找的优秀的代码,别人是用树状数组写的,明显快一些。

我是用线段树写的,思路都差不多。

下面是我写的

#include <iostream>
#include <cstdio>
#include<map>
#include <cstring>
#include<vector>
#include <string>
#include<map>
#include<algorithm>
#include<cmath>
#include<set>
#define mem(a,val) memset(a,val,sizeof a)
#define lef rt<<1
#define rig rt<<1|1
#define fori(l,r) for( int i = l ; i <= r ; i++ )
#define forj(l,r) for( int j = l ; j <= r ; j++ )
#define mid (l+r)>>1
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m;
const int maxn = 1e4+4;

int a[maxn],cpy[maxn];

const int mod = 123456789;

int L,R;
ll ans;

int tree[104][maxn<<2];
void change( int rt,int row )
{
    tree[row][rt] = ( tree[row][lef]+tree[row][rig] )%mod;
}
int query( int l,int r,int rt,int row )
{
    if( l >= L && r <= R )
        return tree[row][rt];
    int m = mid;
    int ans = 0;
    if( m >= L )
        ans = ( ans+query(l,m,lef,row) )%mod;
    if( m < R )
        ans = ( ans+query(m+1,r,rig,row) )%mod;
    return ans;
}
void update( int l,int r,int rt,int position,int val,int row )
{
    if( l == r )
    {
        tree[row][rt] = ( tree[row][rt]+val )%mod;
        return;
    }
    int m = mid;
    if( m >= position )
        update(l,m,lef,position,val,row);
    else update(m+1,r,rig,position,val,row);
    change(rt,row);
}
void getsum( int l,int r,int rt,int row )
{
    if( l == r )
    {
        ans = ( ans+(ll)tree[row][rt] )%mod;
        //cout<<" part ans "<<tree[row][rt]<<" ";
        return;
    }
    int m = mid;
    getsum(l,m,lef,row);
    getsum(m+1,r,rig,row);
}
int main()
{
    while( scanf("%d %d",&n,&m) == 2 )
    {
        mem(tree,0);
        fori(1,n)
        {
            scanf("%d",&a[i]);
            cpy[i] = a[i];
        }
        if( m == 1 )
        {
            printf("%d\n",n);
            continue;
        }
        // ************************************
        sort(cpy+1,cpy+1+n);
        int cnt = unique(cpy+1,cpy+1+n)-cpy;        //离散化
        fori(1,n)
            a[i] = lower_bound(cpy+1,cpy+1+cnt,a[i])-cpy;
        //*************************************
        int t;
        int temp;
        R = cnt;
        ans = 0;
        for( int i = n ; i >= 1 ; i-- )
        {
            L = a[i]+1;

            if( L <= R )
            for( int k = 1 ; k <= m-1 ; k++ )
            {
                temp = query(1,cnt,1,k-1);
                if( k == m-1 )
                    ans = (ans+(ll)temp)%mod;
                update(1,cnt,1,a[i],temp,k);    //点更新,在a[i]处加temp
            }
            update(1,cnt,1,a[i],1,0);   //最下面一层更新
        }
        ans = tree[m-1][1]; //直接得到m长的和
        printf("%I64d\n",ans);
    }
    return 0;
}
/*
6 2
1 3 4 6 2 4
*/


这次没有详细的解释,因为我相信你们写的出来,因为我都写出来了

猜你喜欢

转载自blog.csdn.net/qq_39627843/article/details/81735779