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; }
标签:return,mp,int,res,ll,Tree,2021,MINIEYE,define 来源: https://www.cnblogs.com/lr599909928/p/15069963.html