2021“MINIEYE杯”中国大学生算法设计超级联赛(3)Segment Tree with Pruning (模拟,记忆化)

2021/7/28 14:07:31

本文主要是介绍2021“MINIEYE杯”中国大学生算法设计超级联赛(3)Segment Tree with Pruning (模拟,记忆化),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

  • 题意:对区间\([1,n]\)建线段树,返回条件是\(r-l+1<=k\),问建成的线段树有多少节点.

  • 题解:这题找了半天结论都不对,后来发现可以直接模拟建树过程,对区间长度记忆化,因为区间长度相同,其子节点个数也都是相同的.

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
    
    ll n,k;
    ll cnt=0;
    map<ll,ll> mp;
    
    ll build(ll l,ll r){
        if(mp[r-l+1]) return mp[r-l+1];
        if(r-l+1<=k) return 1;
        ll mid=(l+r)>>1;
        ll res=0;
        res+=build(l,mid);
        res+=build(mid+1,r);
        return mp[r-l+1]=res;
    }
    
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        int _;
        cin>>_;
        while(_--){
            cnt=0;
            cin>>n>>k;
            mp.clear();
            cout<<2*build(1,n)-1<<'\n';
        }
    
    
        return 0;
    }
    


这篇关于2021“MINIEYE杯”中国大学生算法设计超级联赛(3)Segment Tree with Pruning (模拟,记忆化)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程