#pragma once
#include<vector>usingnamespacestd;#include"monotone-minima.hpp"// a は下に凸, b は自由template<typenameT>vector<T>concave_min_plus_convolution(constvector<T>&a,constvector<T>&b){if(a.empty()orb.empty())return{};intn=a.size(),m=b.size();autoargmin=monotone_minima(n+m-1,m,[&](inti,intj,intk){if(i<k)returntrue;if(i-j>=n)returnfalse;returna[i-j]+b[j]<=a[i-k]+b[k];});vector<T>ans(n+m-1);for(inti=0;i<n+m-1;i++){intj=argmin[i];ans[i]=a[i-j]+b[j];}returnans;}// a は上に凸, b は自由template<typenameT>vector<T>concave_max_plus_convolution(constvector<T>&a,constvector<T>&b){if(a.empty()orb.empty())return{};intn=a.size(),m=b.size();autoargmin=monotone_minima(n+m-1,m,[&](inti,intj,intk){if(i<k)returntrue;if(i-j>=n)returnfalse;returna[i-j]+b[j]>=a[i-k]+b[k];});vector<T>ans(n+m-1);for(inti=0;i<n+m-1;i++){intj=argmin[i];ans[i]=a[i-j]+b[j];}returnans;}