Implement the class TweetCounts that supports two methods:
1. recordTweet(string tweetName, int time)

Stores the tweetName at the recorded time (in seconds).

2. getTweetCountsPerFrequency(string freq, string tweetName, int startTime, int endTime)

Returns the total number of occurrences for the given tweetName per minute, hour, or day (depending on freq) starting from the startTime (in seconds) and ending at the endTime (in seconds).
freq is always minute, hour or day, representing the time interval to get the total number of occurrences for the given tweetName.
The first time interval always starts from the startTime, so the time intervals are [startTime, startTime + delta*1>,  [startTime + delta*1, startTime + delta*2>, [startTime + delta*2, startTime + delta*3>, ... , [startTime + delta*i, min(startTime + delta*(i+1), endTime + 1)> for some non-negative number i and delta (which depends on freq).  

 
Example:
Input
["TweetCounts","recordTweet","recordTweet","recordTweet","getTweetCountsPerFrequency","getTweetCountsPerFrequency","recordTweet","getTweetCountsPerFrequency"]
[[],["tweet3",0],["tweet3",60],["tweet3",10],["minute","tweet3",0,59],["minute","tweet3",0,60],["tweet3",120],["hour","tweet3",0,210]]

Output
[null,null,null,null,[2],[2,1],null,[4]]

Explanation
TweetCounts tweetCounts = new TweetCounts();
tweetCounts.recordTweet("tweet3", 0);
tweetCounts.recordTweet("tweet3", 60);
tweetCounts.recordTweet("tweet3", 10);                             // All tweets correspond to "tweet3" with recorded times at 0, 10 and 60.
tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 59); // return [2]. The frequency is per minute (60 seconds), so there is one interval of time: 1) [0, 60> - > 2 tweets.
tweetCounts.getTweetCountsPerFrequency("minute", "tweet3", 0, 60); // return [2, 1]. The frequency is per minute (60 seconds), so there are two intervals of time: 1) [0, 60> - > 2 tweets, and 2) [60,61> - > 1 tweet.
tweetCounts.recordTweet("tweet3", 120);                            // All tweets correspond to "tweet3" with recorded times at 0, 10, 60 and 120.
tweetCounts.getTweetCountsPerFrequency("hour", "tweet3", 0, 210);  // return [4]. The frequency is per hour (3600 seconds), so there is one interval of time: 1) [0, 211> - > 4 tweets.

 
Constraints:

There will be at most 10000 operations considering both recordTweet and getTweetCountsPerFrequency.
0 <= time, startTime, endTime <= 10^9
0 <= endTime - startTime <= 10^4

Difficulty: interview

Starter code:

class TweetCounts:
    def __init__(self):
    def recordTweet(self, tweetName: str, time: int) -> None:
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

Solutions:
from bisect import insort, bisect_left, bisect_right
from math import ceil

class TweetCounts:

    def __init__(self):
        self.tweets={}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = []
        insort(self.tweets[tweetName], time)
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        entry = self.tweets[tweetName]
        diff = endTime - startTime
        factor = 86400
        if freq == 'minute':
            factor = 60
        elif freq == 'hour':
            factor = 3600
        buckets = math.ceil((diff + 1) / factor)
        ans = [0]*buckets
        start = bisect_left(entry, startTime)
        end = bisect_right(entry, endTime)
        for i in range(start, end):
            time = entry[i]
            d = (time - startTime) // factor
            ans[d] += 1
        return ans
        
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from bisect import insort, bisect_left, bisect_right
from math import ceil

class TweetCounts:
    def __init__(self):
        self.tweets = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = []
        insort(self.tweets[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        entry = self.tweets[tweetName]
        diff = endTime - startTime
        factor = 86400
        if freq == 'minute':
            factor = 60
        elif freq == 'hour':
            factor = 3600
        buckets = math.ceil((diff + 1) / factor)
        ans = [0]*buckets
        start = bisect_left(entry, startTime)
        end = bisect_right(entry, endTime)
        for i in range(start, end):
            time = entry[i]
            d = (time - startTime) // factor
            ans[d] += 1
        return ans

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    
    FREQUENCE = {
        'minute' : 60,
        'hour' : 3600,
        'day' : 24*3600,
    }

    def __init__(self):
        self.tweets_dict = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        
        if tweetName not in self.tweets_dict:
            self.tweets_dict[tweetName] = []
        
        bisect.insort(self.tweets_dict.get(tweetName), time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if tweetName not in self.tweets_dict:
            return []
        
        delta = TweetCounts.FREQUENCE[freq]
        
        num_intervals = (endTime - startTime) // delta + 1
        
        result = [0] * num_intervals
        start =  bisect.bisect_left(self.tweets_dict.get(tweetName), startTime)
        end =  bisect.bisect_right(self.tweets_dict.get(tweetName), endTime)
    
        
        for t1 in range(start-1, end+1):
            
            if t1 < 0:
                continue
            if t1 >= len(self.tweets_dict.get(tweetName)):
                continue
            t = self.tweets_dict.get(tweetName)[t1]
            if t<startTime or t>endTime:
                continue
            
            index = (t - startTime) // delta
            result[index] += 1
        
        return result


class TweetCounts:

    def __init__(self):
        from bisect import bisect_left, bisect_right
        from functools import lru_cache
        self.tweets = {}
        self.cache = {}
        return


    def recordTweet(self, tweetName: str, time: int) -> None:
        tn, seconds = tweetName, time
        if tn not in self.tweets: self.tweets[tn] = Counter()
        self.tweets[tn] += Counter(dict([(seconds, 1)]))
        return


    def quantize(self, per_second_tweet_counter, valid_times, scale):
        t = [((timekey-self.st)//scale, per_second_tweet_counter[timekey]) 
             for timekey in valid_times]
        
        qcnts, qkeys = {}, []
        for tk, tc in t:
            if tk not in qcnts:
                qcnts[tk] = 0
                qkeys.append(tk)
            qcnts[tk] += tc

        n = (self.et - self.st + 1) // scale
        if (self.et - self.st + 1) % scale: n += 1
        res = [0] * (n)
        for tk in qkeys: res[tk] = qcnts[tk]
        return res


    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        M, H, D = 60, 60*60, 60*60*24
        self.tn, self.st, self.et = tweetName, startTime, endTime
        if self.tn not in self.tweets: return [0]

        per_second_tweet_counter = self.tweets[self.tn]

        key = (self.tn, self.st, self.et)
        if key in self.cache:
            valid_times = self.cache[key]
        else:
            valid_times = [timekey for timekey in per_second_tweet_counter
                           if self.st <= timekey <= self.et]
            self.cache[key] = valid_times
            
        if freq == 'minute':
            return self.quantize(per_second_tweet_counter, valid_times, M)
        if freq == 'hour':
            return self.quantize(per_second_tweet_counter, valid_times, H)
        if freq == 'day':
            return self.quantize(per_second_tweet_counter, valid_times, D)
        
        return [0]


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    def __init__(self):
        self.store = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.store[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 0
        if freq == \"minute\":
            delta = 60
        elif freq == \"hour\":
            delta = 3600
        else:
            delta = 86400


        result=[0]* ((endTime-startTime)//delta +1)
        if not self.store[tweetName]:
            return result

        times=sorted(self.store[tweetName])
        for time in times:
            if startTime<=time<=endTime:
                result[(time-startTime)//delta]+=1

        return result

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        from bisect import bisect_left, bisect_right
        from functools import lru_cache
        self.tweets = {}
        self.cache = {}
        return


    def recordTweet(self, tweetName: str, time: int) -> None:
        tn, seconds = tweetName, time
        if tn not in self.tweets: self.tweets[tn] = Counter()
        self.tweets[tn] += Counter(dict([(seconds, 1)]))
        return


    def quantize(self, per_second_tweet_counter, valid_times, scale):
        t = [((timekey-self.st)//scale, per_second_tweet_counter[timekey]) 
             for timekey in valid_times]
        
        qcnts, qkeys = {}, []
        for tk, tc in t:
            if tk not in qcnts:
                qcnts[tk] = 0
                qkeys.append(tk)
            qcnts[tk] += tc

        n = (self.et - self.st + 1) // scale
        if (self.et - self.st + 1) % scale: n += 1
        res = [0] * (n)
        for tk in qkeys: res[tk] = qcnts[tk]
        return res


    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        M, H, D = 60, 60*60, 60*60*24
        self.tn, self.st, self.et = tweetName, startTime, endTime
        if self.tn not in self.tweets: return [0]

        per_second_tweet_counter = self.tweets[self.tn]

        key = (self.tn, self.st, self.et)
        if key in self.cache:
            valid_times = self.cache
        else:
            valid_times = [timekey for timekey in per_second_tweet_counter
                           if self.st <= timekey <= self.et]
            
        if freq == 'minute':
            return self.quantize(per_second_tweet_counter, valid_times, M)
        if freq == 'hour':
            return self.quantize(per_second_tweet_counter, valid_times, H)
        if freq == 'day':
            return self.quantize(per_second_tweet_counter, valid_times, D)
        
        return [0]


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        # { 'tweet3': [1,3,1000,5]}
        self.__tweets = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.__tweets:
            self.__tweets[tweetName].append(time)
        else:
            self.__tweets[tweetName] = [time]
        # print(self.__tweets)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if tweetName not in self.__tweets:
            self.__tweets[tweetName] = []
        
        if freq == \"minute\":
            delta = 60
        elif freq == \"hour\":
            delta = 3600
        else: # day
            assert(freq == \"day\"), freq
            delta = 24*3600
        
        # create intervals:
        nextIntervalStart = startTime
        intervals = []
        intervalCount = 1
        while (endTime+1 > nextIntervalStart):
            nextIntervalEnd = startTime + delta*intervalCount
            intervals.append((nextIntervalStart, min(nextIntervalEnd,endTime+1)))
            nextIntervalStart = nextIntervalEnd
            intervalCount += 1
        
        self.__tweets[tweetName].sort()
        result = []
        index = 0
        for interval in intervals:
            result.append(0)
            while (index < len(self.__tweets[tweetName]) 
                   and self.__tweets[tweetName][index] < interval[1]):
                if self.__tweets[tweetName][index] >= interval[0]:
                    result[-1] += 1
                index += 1
        
        return result


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

# TestCases:
\"\"\"
[\"TweetCounts\",\"recordTweet\",\"recordTweet\",\"recordTweet\",\"getTweetCountsPerFrequency\",\"getTweetCountsPerFrequency\",\"recordTweet\",\"getTweetCountsPerFrequency\"]
[[],[\"tweet3\",0],[\"tweet3\",60],[\"tweet3\",10],[\"minute\",\"tweet3\",0,59],[\"minute\",\"tweet3\",0,60],[\"tweet3\",120],[\"hour\",\"tweet3\",0,210]]

[\"TweetCounts\",\"recordTweet\",\"recordTweet\",\"recordTweet\",\"getTweetCountsPerFrequency\",\"getTweetCountsPerFrequency\",\"recordTweet\",\"getTweetCountsPerFrequency\"]
[[],[\"tweet3\",0],[\"tweet3\",60],[\"tweet3\",10],[\"minute\",\"tweet3\",0,59],[\"minute\",\"tweet3\",0,60],[\"tweet3\",120],[\"day\",\"tweet3\",0,210]]

[\"TweetCounts\",\"recordTweet\",\"recordTweet\",\"recordTweet\",\"getTweetCountsPerFrequency\",\"getTweetCountsPerFrequency\",\"recordTweet\",\"getTweetCountsPerFrequency\"]
[[],[\"tweet3\",0],[\"tweet3\",60],[\"tweet3\",10],[\"minute\",\"tweet3\",0,59],[\"minute\",\"tweet3\",0,60],[\"tweet3\",120],[\"hour\",\"tweet3\",0,0]]

[\"TweetCounts\"]
[[]]

[\"TweetCounts\",\"recordTweet\",\"recordTweet\",\"recordTweet\",\"getTweetCountsPerFrequency\",\"getTweetCountsPerFrequency\",\"recordTweet\",\"getTweetCountsPerFrequency\",\"recordTweet\",\"recordTweet\", \"getTweetCountsPerFrequency\", \"getTweetCountsPerFrequency\"]
[[],[\"tweet3\",0],[\"tweet3\",60],[\"tweet3\",10],[\"minute\",\"tweet3\",0,59],[\"minute\",\"tweet3\",0,30],[\"tweet3\",120],[\"hour\",\"tweet3\",0,210],[\"tweet3\",420],[\"tweet1\",120],[\"minute\",\"tweet3\",0,1000], [\"day\",\"tweet3\",0,500000]]


\"\"\"

class TweetCounts:

    def __init__(self):
        self.a = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        heapq.heappush(self.a[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if tweetName not in self.a:
            return []
        temp = list(self.a[tweetName])
        q = []
        while temp:
            q.append(heapq.heappop(temp))
        if freq == 'minute':
            f = 60
        elif freq == 'hour':
            f = 3600
        else:
            f = 3600 * 24
                
        bucket_size = (endTime - startTime) // f + 1
        ans = [0] * bucket_size
        cur = 0
        end = f + startTime
        for t in q:
            if t < startTime: continue
            if t > endTime: break
            i = (t - startTime) // f
            ans[i] += 1
        
        return ans
            
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    class TreeNode:
        def __init__(self,time,val=1,left=None,right=None):
            self.time = time
            self.val = val
            self.left = left
            self.right = right
            
    def __init__(self):
        self.tweets = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        def radd(root):
            if root.time == time:
                root.val += 1
            elif root.time > time:
                if root.left is None:
                    root.left = self.TreeNode(time)
                else:
                    radd(root.left)
            else:
                if root.right is None:
                    root.right = self.TreeNode(time)
                else:
                    radd(root.right)
        if tweetName not in self.tweets:
            self.tweets[tweetName] = self.TreeNode(time)
        else:
            radd(self.tweets[tweetName])

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        def rech(root,buckets,s):
            if root is not None:
                rech(root.left,buckets,s)
                if startTime <= root.time <= endTime:
                    while (startTime+len(buckets)*s)-1 < root.time: buckets.append(0)
                    buckets[-1] += root.val
                rech(root.right,buckets,s)
            return buckets
        s = 60 if freq == \"minute\" else 3600 if freq == \"hour\" else 86400
        buckets = rech(self.tweets[tweetName],[0],s)
        while (startTime+len(buckets)*s)-1 < endTime: buckets.append(0)
        return buckets
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.lst = []

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.lst.append((time, tweetName))

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        seconds=[24*3600, 3600, 60]
        F=[\"day\", \"hour\", \"minute\"]
        idx = F.index(freq)
        start = startTime
        end = endTime
        
        lens = (end-start+1+seconds[idx]-1)//seconds[idx]
        

        rs = [0]*lens
        for i, v in enumerate(self.lst):
            t = v[0]
            if t >= start and t <= end:
                if v[1] == tweetName:
                    #print(t, start, end, v[1])
                    rs[(t-start)//seconds[idx]] += 1
        return rs


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.map = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.map:
            self.map[tweetName].append(time)
        else:
            self.map[tweetName] = [time] 

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 0
        if freq == \"minute\": 
            delta = 60
        elif freq == \"hour\":
            delta = 3600
        else:
            delta =60*60*24

#         if(freq == 'minute'):
#             secs = 60
#             size = (endTime - startTime) / 60 + 1
#         if(freq == 'hour'):
#             secs = 3600
#             size = (endTime - startTime) / 3600 + 1
#         if(freq == 'day'):
#             secs = 86400
#             size = (endTime - startTime) / 86400 + 1
                
#         r = [0] * int(size)
        
#         for i in times:
#             if(startTime <= i and i <= endTime):
#                 index = int((i-startTime)/secs)
#                 r[index] += 1
        
        #value list
        self.map[tweetName].sort()
        tweetTimes = self.map[tweetName]
        
        
        size = (endTime-startTime)//delta+1
        res = [0]*size
             
        #for loop that goes through time intervals and counts # of tweets in that interval
        startRange = 0
        endRange = 0
        secs = delta
        for i in range(0, (size)):
            startRange = startTime + delta*i
            endRange = min(startTime + delta*(i+1), endTime+1)

            for tweetTime in tweetTimes:
                if tweetTime >= endRange:
                    break
                if tweetTime >= startRange and tweetTime < endRange:
                    index = int((tweetTime-startTime)/secs)
                    res[index] +=1
            
        return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

import collections
import bisect

class TweetCounts:
    
    FREQ_TO_SECONDS = {
        \"minute\": 60,
        \"hour\": 60*60,
        \"day\": 24*60*60,
    }

    def __init__(self):
        self.tweets = collections.defaultdict(list)
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        
        self.tweets[tweetName].insert(bisect.bisect_left(self.tweets[tweetName], time), time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = self.FREQ_TO_SECONDS[freq]
        tweets = self.tweets.get(tweetName, [])
        results = []
        
        if not tweets:
            return []
        
        while startTime <= endTime:
            upper_bound = min(endTime, startTime+delta-1)
            values = [time for time in tweets if time>=startTime and time<=upper_bound]
            results.append(len(values))
            startTime += delta
            
        return results
        
        
        
        
        
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        start = startTime
        res = []
        self.data[tweetName].sort()
        while start <= endTime:
            end = min(start + delta, endTime + 1)
            res.append(len([x for x in self.data[tweetName] if start <= x < end]))
            start += delta
        return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    
    FREQUENCE = {
        'minute' : 60,
        'hour' : 3600,
        'day' : 24*3600,
    }

    def __init__(self):
        self.tweets_dict = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        
        if tweetName not in self.tweets_dict:
            self.tweets_dict[tweetName] = []
        
        bisect.insort(self.tweets_dict.get(tweetName), time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if tweetName not in self.tweets_dict:
            return []
        
        delta = TweetCounts.FREQUENCE[freq]
        
        num_intervals = (endTime - startTime) // delta + 1
        
        result = [0] * num_intervals
        
        for t in self.tweets_dict[tweetName]:
            if t < startTime:
                continue
            if t > endTime:
                break
            
            index = (t - startTime) // delta
            result[index] += 1
        
        return result


from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):     
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        start = startTime
        res = []
        self.data[tweetName].sort()
        while start <= endTime:
            end = min(start + delta, endTime + 1)
            res.append(len([x for x in self.data[tweetName] if start <= x < end]))
            # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
            start += delta
        return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = {} # {name:[n1,n2,n3]}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets.keys():
            self.tweets[tweetName] = []
        self.tweets[tweetName].append(time)
        # self.tweets[tweetName].sort()
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if freq == \"hour\":
            gap = 60*60
        elif freq == \"day\":
            gap = 24*60*60
        else:
            gap = 60
            
        res = []
        if tweetName not in self.tweets.keys():
            return res
        
        tm = self.tweets[tweetName]
        
        for i in range(startTime, endTime+1, gap):
            sum=0
            end = min(i+gap, endTime+1)
            print(f\"i:{i} end:{end}\")
            
            for t in tm:
                if t >= i and t < end:
                    sum+=1
            res.append(sum)
            
        return res
        
        
            
        
                    
                    
                    


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime): 
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # new_data = [x for x in self.data[tweetName] if startTime <= x <= endTime]
        # delta_data = [(x - startTime) // delta for x in new_data]
        # n = (endTime - startTime) // delta + 1
        # res = [len([x for x in delta_data if x == i]) for i in range(n)]
        # return res
        
        
        
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        start = startTime
        res = []
        while start <= endTime:
            end = min(start + delta, endTime + 1)
            res.append(len([x for x in self.data[tweetName] if start <= x < end]))
            # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
            start += delta
        return res        

        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # start = startTime
        # res = []
        # self.data[tweetName].sort()
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        start = startTime
        res = []
        while start <= endTime:
            end = min(start + delta, endTime + 1)
            res.append(len([x for x in self.data[tweetName] if start <= x < end]))
            start += delta
        return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = []
        left, right = 0, len(self.tweets[tweetName])
        while left < right:
            mid = left + (right-left)//2
            if self.tweets[tweetName][mid]>=time:
                right = mid
            else:
                left = mid+1
        self.tweets[tweetName].insert(left, time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = {\"minute\": 60, \"hour\": 60*60, \"day\": 60*60*24}
        interval = delta[freq]
        num_intervals = (endTime - startTime) // interval + 1
        count = [0] * num_intervals
        for t in self.tweets[tweetName]:
            if t<startTime:
                continue
            if t>endTime:
                break
            count[(t - startTime) // interval]+=1
        return count


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        insort(self.tweets[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 60
        if freq == 'hour':
            delta = 3600
        elif freq == 'day':
            delta = 86400
        
        pre = bisect_left(self.tweets[tweetName], startTime)
        n = (endTime + 1 - startTime)//delta + (1 if (endTime+1-startTime) % delta != 0 else 0)
        end, res = startTime, []
        for _ in range(n):
            end = min(end + delta, endTime + 1)
            i = bisect_left(self.tweets[tweetName], end)
            res.append(i - pre)
            pre = i
        return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.data = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.data[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        T, d = self.data[tweetName], 60 if freq == \"minute\" else (3600 if freq == \"hour\" else 86400)
        # ans = [bisect.bisect(T, t+d) - bisect.bisect_left(T, t) for t in range(startTime, endTime, d)]
        ans = [0]*((endTime-startTime)//d + 1)
        if not T or endTime < T[0] or startTime > T[-1]:
            return ans
        i, l = 0, bisect.bisect_left(T, startTime)
        r = bisect.bisect(T, endTime, lo=l)
        #print(\"T, d, l, r, T[l:r], ans:\", T, d, l, r, T[l:r], ans)
        for t in range(startTime+d, endTime+1, d):
            m = bisect.bisect_left(T, t, lo=l, hi=r)
            ans[i] = m-l
            #print(\"i, l, m, ans:\", i, l, m, ans)
            l = m; i += 1
        ans[i] = r-l
        return ans


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:
    
    FREQUENCE = {
        'minute' : 60,
        'hour' : 3600,
        'day' : 24*3600,
    }

    def __init__(self):
        self.tweets_dict = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        
        if tweetName not in self.tweets_dict:
            self.tweets_dict[tweetName] = []
        
        left, right = 0, len(self.tweets_dict[tweetName])
        # left bound
        while left < right:
            mid = left + (right - left) // 2
            if self.tweets_dict[tweetName][mid] == time:
                right = mid
            elif self.tweets_dict[tweetName][mid] > time:
                right = mid
            elif self.tweets_dict[tweetName][mid] < time:
                left = mid + 1
        self.tweets_dict[tweetName].insert(left, time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if tweetName not in self.tweets_dict:
            return []
        
        delta = TweetCounts.FREQUENCE[freq]
        
        num_intervals = (endTime - startTime) // delta + 1
        
        result = [0] * num_intervals
        
        for t in self.tweets_dict[tweetName]:
            if t < startTime:
                continue
            if t > endTime:
                break
            
            index = (t - startTime) // delta
            result[index] += 1
        
        return result

class TweetCounts:

    def __init__(self):
        self.store = defaultdict(list)
        self.delta = {'hour': 3600, 'minute': 60, 'day': 24 * 3600}
        
    def recordTweet(self, tn: str, time: int) -> None:
        insort(self.store[tn], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        d = self.delta[freq]
        ans = []
        arr = self.store[tweetName]
        
        for st_time in range(startTime, endTime+1, d):
            left = bisect_left(arr, st_time)
            right = bisect_right(arr, min(endTime, st_time + d - 1))
            
            ans.append(right - left)
        
        return ans


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict
from enum import Enum
from math import ceil

frequency= Enum(
    value='frequency',
    names=[
        ('minute', 60),
        ('hour', 3600),
        ('day', 86400)
    ])

class TweetManager:
    def __init__(self):
        self.tweets = defaultdict(list)
    
    def __str__(self):
        return str(self.tweets)
    
    def add_tweet(self, tweet_name, time):
        self.tweets[tweet_name].append(time)
        self.tweets[tweet_name].sort()
    
    def _find_start_index(self, history: List[int], start_time, min_index=None, max_index=None):
        if min_index is None:
            min_index = 0
        if max_index is None:
            max_index = len(history) - 1
        if min_index > max_index:
            return None
        middle_index = int((max_index + min_index)/2)
        #print(f'# find start index: middle_index={middle_index}, start_time={start_time}, min_index={min_index}, max_index={max_index}')
        #print('# history[middle_index]: ', history[middle_index])
        if history[middle_index] == start_time:
            #print('# GOT IT')
            return middle_index
        if history[middle_index] > start_time:
            result = self._find_start_index(history, start_time, min_index, middle_index-1)
            if result is None:
                #print('# sort of got it')
                return middle_index
            return result
        if history[middle_index] < start_time:
            return self._find_start_index(history, start_time, middle_index+1, max_index)
            
            
    def _find_end_index(self, history: List[int], end_time, min_index=None, max_index=None):
        if min_index is None:
            min_index = 0
        if max_index is None:
            max_index = len(history) - 1
        if min_index > max_index:
            return None
        middle_index = int((max_index + min_index)/2)
        #print(f'# find end index: middle_index={middle_index}, end_time={end_time}, min_index={min_index}, max_index={max_index}')
        #print('# history[middle_index]: ', history[middle_index])
        if history[middle_index] == end_time:
            #print('# GOT IT')
            return middle_index
        if history[middle_index] > end_time:
            return self._find_end_index(history, end_time, min_index, middle_index-1)
        if history[middle_index] < end_time:
            result = self._find_end_index(history, end_time, middle_index+1, max_index)
            if result is None:
                #print('# sort of got it')
                return middle_index
            return result
    
    def _calculate_frequency(self, history: List[int], start_index, end_index, freq, end_time, start_time):
        #print(f'# calculate frequency - end_time: {end_time}, start_time: {start_time}')
        
        if start_index is None or end_index is None:
            history = []
        else:
            history = history[start_index:end_index+1]
        
        previous_bucket = None
        result = []
        bucket = None
        for time_seconds in history:
            bucket = 0 if (time_seconds+1-start_time) / frequency[freq].value <= 1 else int((time_seconds+1-start_time) / frequency[freq].value)
            #print('### bucket: ', bucket)
            
            empty_buckets = bucket - (previous_bucket if previous_bucket else 0)
            if previous_bucket is None:
                empty_buckets +=1
            if empty_buckets > 1:
                #print('# empty buckets: ', empty_buckets)
                for a in range(empty_buckets):
                    result.append(0)
            
            if len(result) == bucket:
                result.append(1)
            else:
                result[bucket] += 1
                
            previous_bucket = bucket
        
        max_bucket = 0 if (end_time-start_time) / frequency[freq].value < 1 else int((end_time-start_time) / frequency[freq].value)
        
        #print('### max bucket: ', max_bucket)
        if bucket is None:
            while max_bucket >= 0:
                result.append(0)
                max_bucket -= 1
        else:
            while max_bucket > bucket:
                result.append(0)
                max_bucket -= 1
        
        
        return result
    
    def get_tweet_frequency(self, tweet_name: str, start_time: int, end_time: int, freq) -> List[int]:
        #print()
        start_index = self._find_start_index(self.tweets.get(tweet_name), start_time)
        end_index = self._find_end_index(self.tweets.get(tweet_name), end_time)
        #print(f'# start_index: {start_index}, end_index: {end_index}')
        
        result_frequency = self._calculate_frequency(self.tweets.get(tweet_name), start_index, end_index, freq, end_time, start_time)
        
        #print('# result frequency: ', result_frequency)
        
        #return start_index, end_index
        return result_frequency
        
        
    

class TweetCounts:
    def __init__(self):
        self.tweets = TweetManager()

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets.add_tweet(tweetName, time)
        
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        #print('# tweet history: ', self.tweets)
        return self.tweets.get_tweet_frequency(tweetName, startTime, endTime, freq)
        
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict
from bisect import bisect_left, insort
class TweetCounts:

    def __init__(self):
        self.history = defaultdict(list)

    def recordTweet(self, tweet, t):
        insort(self.history[tweet], t)

    def getTweetCountsPerFrequency(self, freq, tweet, s, e):
        if freq == 'minute':
            delta = 60
        elif freq == 'hour':
            delta = 3600
        else:
            delta = 86400
        A, cur = self.history[tweet], s
        res = []
        while cur <= e:
            nxt = min(cur+delta, e+1)
            occurence = bisect_left(A, nxt) - bisect_left(A, cur)
            res.append(occurence)
            cur += delta
        return res
            
            
        
        
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from sortedcontainers import SortedList

class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(SortedList)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].add(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        tweets = self.tweets[tweetName]
        if not tweets:
            return []
        
        bucket_size = {\"minute\": 60, \"hour\": 3600, \"day\": 3600*24}[freq]
        num_buckets = ceil((endTime-startTime)/bucket_size)
        if (endTime - startTime) % bucket_size == 0:
            num_buckets += 1
        buckets = [0] * num_buckets
        for t in tweets.irange(startTime, endTime):
            bucket_idx = floor((t - startTime) / bucket_size)
            buckets[bucket_idx] += 1
            
        return buckets
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:
    SECONDS = {
        \"minute\": 60,
        \"hour\":   60 * 60,
        \"day\":    60 * 60 * 24, 
    }

    def __init__(self):
        self.tweets = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.tweets[tweetName], time)
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        count = math.ceil((endTime - startTime + 1) / TweetCounts.SECONDS[freq])
        prev = bisect.bisect_left(self.tweets[tweetName], startTime)
        ans = []
        for i in range(1, count+1):
            cur = bisect.bisect_left(self.tweets[tweetName],
                                     min(startTime + i * TweetCounts.SECONDS[freq], endTime+1))
            ans.append(cur - prev)
            prev = cur
        return ans

class TweetCounts:

    def __init__(self):
        self.store = defaultdict(list)
        self.delta = {'hour': 3600, 'minute': 60, 'day': 24 * 3600}
        
    def recordTweet(self, tn: str, time: int) -> None:
        insort(self.store[tn], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        d = self.delta[freq]
        ans = []
        arr = self.store[tweetName]
        
        for st_time in range(startTime, endTime+1, d):
            left = bisect_left(arr, st_time)
            right = bisect_right(arr, min(endTime, st_time + d - 1)) - 1
            
            # print(st_time, st_time + d - 1, left, right)
            
            
            ans.append(min(right - left + 1, len(arr)))
        
        return ans


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.recorder = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.recorder[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        res, i, start = [], 1, startTime
        while start <= endTime:
            end = min(startTime + delta * i, endTime + 1)
            res.append(bisect_left(self.recorder[tweetName], end) - bisect_left(self.recorder[tweetName], start))
            start, i = end, i + 1
        return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    FREQUENCEY_TO_SECONDS = {
        'minute': 60,
        'hour': 3600,
        'day': 86400
    }

    def __init__(self):
        self._data = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self._data[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = self.FREQUENCEY_TO_SECONDS.get(freq.lower(), None)
        if not delta:
            return []

        i, result = startTime, []

        while i <= endTime:
            j = min(i + delta, endTime + 1)
            left = bisect.bisect_left(self._data[tweetName], j)
            right = bisect.bisect_left(self._data[tweetName], i)
            result.append(left - right)
            i += delta

        return result

import bisect
from collections import defaultdict

class TweetCounts:

    def __init__(self):
        self._tweets = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self._tweets[tweetName].insert(
            bisect.bisect_right(self._tweets[tweetName], time), time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        
        result = []
        while startTime <= endTime:
            end = min(startTime + delta, endTime + 1)
            result.append(
                bisect.bisect_left(self._tweets[tweetName], end) -
                    bisect.bisect_left(self._tweets[tweetName], startTime))
            startTime += delta
        return result
            

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


import bisect
from collections import defaultdict

class TweetCounts:

    def __init__(self):
        self._tweets = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self._tweets[tweetName].insert(
            bisect.bisect_left(self._tweets[tweetName], time), time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        
        result = []
        while startTime <= endTime:
            end = min(startTime + delta, endTime + 1)
            result.append(
                bisect.bisect_left(self._tweets[tweetName], end) -
                    bisect.bisect_left(self._tweets[tweetName], startTime))
            startTime += delta
        return result
            

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.a = defaultdict(list)

    def recordTweet(self, tn: str, time: int) -> None:
        bisect.insort(self.a[tn], time)
       
    def getTweetCountsPerFrequency(self, freq: str, tn: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        i = startTime
        res = []
        while i <= endTime:
            j = min(i + delta, endTime+1)
            res.append(bisect_left(self.a[tn], j) - bisect_left(self.a[tn], i))
            i += delta
        return res


        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.a = defaultdict(list)

    def recordTweet(self, tn: str, time: int) -> None:
        bisect.insort(self.a[tn], time)
       
    def getTweetCountsPerFrequency(self, freq: str, tn: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        i = startTime
        res = []
        while i <= endTime:
            j = min(i + delta, endTime+1)
            res.append(bisect_left(self.a[tn], j) - bisect_left(self.a[tn], i))
            i += delta
        return res
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from sortedcontainers import SortedList
class TweetCounts:

    def __init__(self):
        self.timeStamps = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.timeStamps:
            self.timeStamps[tweetName] = SortedList({})
        self.timeStamps[tweetName].add(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = None
        if freq == \"minute\":
            delta = 60
        elif freq == \"hour\":
            delta = 3600
        else:
            delta = 86400
        answer = []
        ##need to essentially figure out the first tweet in self.timeStamps[tweetName] that comes at least at startTime and then go on by the delta until we see that we exceed endTime. We will have to stop along the way if our endTime is greater than current time plus delta and then append to answer and create new List.
        if tweetName in self.timeStamps:
            startIndex = self.timeStamps[tweetName].bisect_left(startTime)
            timeStampLength = len(self.timeStamps[tweetName])
            currentIndex = startIndex
            lowerBound = startTime
            upperBound = min(lowerBound+delta-1,endTime)
            while True:##if we see that the currentIndex is already too large then we will have that the count = 0
                count = 0
                currentTime = self.timeStamps[tweetName][currentIndex] if currentIndex < timeStampLength else float('inf')##this will ensure that we still put in 0s for count if our timestamp is way to far ahead already
                while currentTime >= lowerBound and upperBound >= currentTime:
                    count += 1
                    currentIndex += 1
                    if currentIndex >= timeStampLength:
                        break
                    else:
                        currentTime = self.timeStamps[tweetName][currentIndex]
                answer.append(count)
                lowerBound += delta
                if lowerBound > endTime:
                    break
                else:
                    upperBound = min(lowerBound+delta-1,endTime)
        return answer


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.data = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.data[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        T, d = self.data[tweetName], 60 if freq == \"minute\" else (3600 if freq == \"hour\" else 86400)
        ans = [0]*((endTime-startTime)//d + 1)
        for i in range(bisect.bisect_left(T, startTime), bisect.bisect(T, endTime)):
            ans[(T[i]-startTime)//d] += 1
        return ans
    

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:
    FREQUENCEY_TO_SECONDS = {
        'minute': 60,
        'hour': 3600,
        'day': 86400
    }

    def __init__(self):
        self._data = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self._data[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = self.FREQUENCEY_TO_SECONDS.get(freq, None)
        if not delta:
            return []

        i, result = startTime, []

        while i <= endTime:
            j = min(i + delta, endTime + 1)
            left = bisect.bisect_left(self._data[tweetName], j)
            right = bisect.bisect_left(self._data[tweetName], i)
            result.append(left - right)
            i += delta

        return result

freq_map = {\"minute\": 60, \"hour\": 3600, \"day\": 24*3600}
class TweetCounts:

    def __init__(self):
        self.tweet_dict = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweet_dict:
            self.tweet_dict[tweetName] = []
        self.tweet_dict[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if tweetName not in self.tweet_dict:
            return None
        intervals = (-startTime + endTime)//freq_map[freq] + 1
        output = [0]*intervals
        for elem in self.tweet_dict[tweetName]:
            if elem >= startTime and elem <= endTime:
                output[(elem - startTime)//freq_map[freq]] += 1
        return output

        # Your TweetCounts object will be instantiated and called as such:
        # obj = TweetCounts()
        # obj.recordTweet(tweetName,time)
        # param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = {}
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in list(self.tweets.keys()):
            bisect.insort(self.tweets[tweetName], time)
        else:
            self.tweets[tweetName] = [time]
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if tweetName not in self.tweets:
            return []
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400 
        time_list = self.tweets[tweetName]
        
        size = int((endTime-startTime)//delta) +1
        res = [0]*size
        for t in time_list:
            if startTime <= t <= endTime:
                index = int((t-startTime)//delta)
                res[index] += 1        
        
        # i = delta
        # if len(time_list) == 1:
        #     if time_list[0] < startTime or time_list[0] > endTime:
        #         res.append([0]*size)
        #         return res[0]
        # while startTime <= endTime:
        #     while i < startTime:
        #         i+=delta
        #     count = 0
        #     for t in time_list:
        #         if startTime <= t <i:
        #             count += 1
        #     res.append(count)
        #     startTime += delta
        #     i += delta
        return res
    

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    def __init__(self):
        self.tweets = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = []
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq == \"minute\":
            delta = 60
        elif freq == \"hour\":
            delta = 60*60
        else:
            delta = 60*60*24
            
        result = [0] * (((endTime - startTime) // delta) + 1)
        for tweetTime in self.tweets[tweetName]:
            if startTime <= tweetTime <= endTime:
                result[((tweetTime - startTime) // delta)] += 1
        return result

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict
from bisect import insort, bisect_left
class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)
        self.d = {'minute':60, 'hour': 3600, 'day': 86400}

    def recordTweet(self, tweetName: str, time: int) -> None:
        # insort(self.tweets[tweetName], time)
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        record = self.tweets[tweetName]
        delta = self.d[freq]
        # Solution 2: loop through the whole record O(n)
        res = [0] * ((endTime - startTime) // delta + 1) # total interval
        for time in record: # loop through time in record
            if time < startTime or time > endTime:
                continue
            res[(time - startTime) // delta] += 1
        return res
        # Solution 1: Binary search O(logn)
        # res = []
        # i = startTime
        # while i <= endTime:
        #     j = min(i + delta, endTime + 1)
        #     res.append(bisect_left(record, j) - bisect_left(record, i))
        #     i += delta
        # return res
        
        # not efficient solution
        # low = bisect_left(record, startTime)
        # res = [0]
        # start, idx, j = startTime, low, 1
        # print (record[idx:], startTime, endTime, delta)
        # while idx < len(record) and record[idx] <= endTime:
        #     if record[idx] < start + delta*j:
        #         res[j-1] += 1
        #     else:
        #         j += 1
        #         res.append(1)
        #         start += delta
        #     idx += 1
        # print (res)
        # return res




# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets.setdefault(tweetName, []).append(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq == \"minute\":
            seconds = 60
        elif freq == \"hour\":
            seconds = 3600
        else:
            seconds = 86400
        rep = (endTime-startTime)//seconds+1
        ans = [0 for _ in range(rep)]
        for tweet_time in self.tweets[tweetName]:
            if startTime<=tweet_time<=endTime:
                ans[(tweet_time-startTime)//seconds]+=1
        return ans


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.map = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.map:
            self.map[tweetName].append(time)
        else:
            self.map[tweetName] = [time] 

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if freq == \"minute\": seconds = 60 
        elif freq == \"hour\": seconds = 3600
        else: seconds = 86400
        
        ans = [0] * ((endTime - startTime)//seconds + 1)
        for t in self.map[tweetName]:
            if startTime <= t <= endTime: ans[(t-startTime)//seconds] += 1
        return ans 
        
#         times = self.map[tweetName]
        
#         size = 0 
#         delta = 0
        
#         if(freq == 'minute'):
#             delta = 60
#             size = (endTime - startTime) / delta + 1
#         if(freq == 'hour'):
#             delta = 3600
#             size = (endTime - startTime) / delta + 1
#         if(freq == 'day'):
#             delta = 86400
#             size = (endTime - startTime) / delta + 1
                
#         r = [0] * int(size)
        
#         for i in times:
#             if(startTime <= i and i <= endTime):
#                 index = int((i-startTime)/delta)
#                 r[index] += 1

#         return r  
    
    

#         delta = 0
#         if freq == \"minute\": 
#             delta = 60
#         elif freq == \"hour\":
#             delta = 3600
#         else:
#             delta =60*60*24
        
#         #value list
#         self.map[tweetName].sort()
#         tweetTimes = self.map[tweetName]
        
        
#         size = (endTime-startTime)//delta+1
#         res = [0]*size
             
#         #for loop that goes through time intervals and counts # of tweets in that interval
#         startRange = 0
#         endRange = 0
#         secs = delta
#         for i in range(0, (size)):
#             startRange = startTime + delta*i
#             endRange = min(startTime + delta*(i+1), endTime+1)

#             for tweetTime in tweetTimes:
#                 if tweetTime >= endRange:
#                     break
#                 if tweetTime >= startRange and tweetTime < endRange:
#                     index = int((tweetTime-startTime)/secs)
#                     res[index] +=1
            
#         return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.records = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.records[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        record = self.records[tweetName]
        dt = 60
        if freq == \"hour\":
            dt *= 60
        elif freq == \"day\":
            dt *= 60 * 24
        res = [0] * ((endTime-startTime) // dt + 1)
        
        for t in record:
            if startTime <= t <= endTime:
                idx = (t - startTime) // dt
                res[idx] += 1
        return res

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.memo = collections.defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.memo[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        lst = self.memo[tweetName]
        lst = [t-startTime for t in lst if t>=startTime and t<=endTime]
        if freq == 'minute':
            freq = 60
        elif freq== 'hour':
            freq = 60*60
        elif freq == 'day':
            freq = 24*60*60
        length, remainder = divmod(endTime-startTime+1, freq)
        if remainder>0:
            length += 1
        res = [0 for _ in range(length)]
        # print (t_max, freq)
        for t in lst:
            res[t//freq] += 1
        return res
        
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict
class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        times = self.tweets[tweetName]
        
        if freq == \"minute\":
            seconds = 60
        elif freq == \"hour\":
            seconds = 60 * 60
        elif freq == \"day\":
            seconds = 60 * 60 * 24
        
        output_len = ((endTime - startTime)/seconds) + 1
        output = [0] * int(output_len)
        
        for time in times:
            if time >= startTime and time <= endTime:
                index = int((time - startTime)/seconds)
                output[index] += 1
        
        return output
    
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = collections.defaultdict(list)
        self.convert = {'minute': 60, 'hour':3600, 'day': 86400}

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        seconds = self.convert[freq]
        ans = [0] * ((endTime - startTime)//seconds + 1)
        for time in self.tweets[tweetName]:
            if startTime <= time <= endTime:
                ans[(time-startTime)//seconds] += 1
        return ans           
            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict


class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        times = self.tweets[tweetName]
        length = endTime - startTime
        
        if freq == \"minute\":
            units = 60
        elif freq == \"hour\":
            units = 3600
        else:
            units = 3600 * 24
            
        intervals = {}
        i = 0
        for _ in range(startTime, endTime + 1, units):
            intervals[i] = 0
            i += 1
            
        for t in times:
            if startTime <= t <= endTime:
                interval = (t - startTime) // units
                intervals[interval] += 1
                
        return list(intervals.values())


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.tweets = collections.defaultdict(list)
        self.convert = {'minute': 60, 'hour':3600, 'day': 86400}

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        ans = [0] * ((endTime - startTime)//self.convert[freq] + 1)
        for t in self.tweets[tweetName]:
            if startTime <= t <= endTime: ans[(t-startTime)//self.convert[freq]] += 1
        return ans           
            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = dict()

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets.setdefault(tweetName, []).append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq == \"minute\": seconds = 60 
        elif freq == \"hour\": seconds = 3600
        else: seconds = 86400
        
        ans = [0] * ((endTime - startTime)//seconds + 1)
        for t in self.tweets[tweetName]:
            if startTime <= t <= endTime: ans[(t-startTime)//seconds] += 1
        return ans           
            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict

import bisect

class TweetCounts:

  def __init__(self):
    self.T = defaultdict(lambda: [False, []])

  def recordTweet(self, tweetName: str, time: int) -> None:
    self.T[tweetName][0] = False
    self.T[tweetName][1].append(time)

  def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
    delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
    if not self.T[tweetName][0]:
      self.T[tweetName][1].sort()
    ans = []
    s = startTime
    i = bisect.bisect_left(self.T[tweetName][1], s)
    while s <= endTime:
      e = min(s + delta, endTime + 1)
      j = bisect.bisect_left(self.T[tweetName][1], e)
      ans.append(j - i)
      s, i = e, j
    return ans

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    
    deltaDic = {
        'minute': 60, 
        'hour': 3600,
        'day': 24 * 3600,
    }

    def __init__(self):
        self.tweetDic = {}
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        if not tweetName in self.tweetDic:
            self.tweetDic[tweetName] = []
        self.tweetDic[tweetName].append(time)
        self.tweetDic[tweetName].sort()

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if not tweetName in self.tweetDic:
            return []
        
        delta = self.deltaDic[freq]
        output = [0] * ((endTime - startTime) // delta + 1)
        for t in self.tweetDic[tweetName]:
            if t < startTime:
                continue
            elif t > endTime:
                continue
            else:
                idx = (t - startTime) // delta
                output[idx] += 1
        
        return output

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.a = defaultdict(list)

    def recordTweet(self, tn: str, time: int) -> None:
        bisect.insort(self.a[tn], time)
       
    def getTweetCountsPerFrequency(self, freq: str, tn: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        i = startTime
        res = []
        while i <= endTime:
            j = min(i + delta, endTime+1)
            res.append(bisect_left(self.a[tn], j) - bisect_left(self.a[tn], i))
            i += delta
        return res

class TweetCounts:

    def __init__(self):
        self.d={}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.d:
            self.d[tweetName]=[time]
        else:
            self.d[tweetName].append(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq=='minute':
            s=60
        elif freq=='hour':
            s=3600
        else:
            s=3600*24
        
        intervals=(endTime-startTime)//s+1
        
        res=[0]*intervals
        times=self.d[tweetName]
        for t in times:
            if startTime<=t<=endTime:
                i=(t-startTime)//s
                res[i]+=1
        return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict
from bisect import bisect_left, bisect_right

TIME_OFFSETS = {
    \"minute\": 60,
    \"hour\": 60 * 60,
    \"day\": 24 * 60 * 60
}

class TweetCounts:

    def __init__(self):
        self._tweets = defaultdict(list)
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        tweets = self._tweets[tweetName]
        
        pos = bisect_left(tweets, time)
        self._tweets[tweetName] = tweets[:pos] + [time] + tweets[pos:]
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        tweets = self._tweets[tweetName]
        if not tweets:
            return 0
        
        offset = TIME_OFFSETS[freq]
        result = []
        
        for t in range(startTime, endTime + 1, offset):
            t2 = min(endTime, t + offset - 1)
            pos = bisect_left(tweets, t)
            end_pos = bisect_right(tweets, t2)
            result.append(end_pos - pos)
            pos = end_pos

        return result
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.tweets=defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        count=0
        den=0
        size = 0 
        if freq=='minute':
            den=60
            size=(endTime-startTime)//60+1
        elif freq=='hour':
            den=3600
            size=(endTime-startTime)//3600+1
        else:
            den=86400
            size =(endTime-startTime)//86400+1
        op=[0]*size
        
        for t in self.tweets[tweetName]:
            if(startTime<=t and t<=endTime):
                idx=(t-startTime)//den
                op[idx]+=1

        return op         
        
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


# 832
class TweetCounts:

    def __init__(self):
      self.log = defaultdict(list)
        

    def recordTweet(self, tweetName: str, time: int) -> None:
      self.log[tweetName].append(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
      ret = []
      events = sorted([t for t in self.log[tweetName] if startTime <= t <= endTime])
      ei = 0
      time = startTime
      delta = {'minute': 60, 'hour': 3600, 'day': 24 * 3600}[freq]
      
      #print(events)
      
      cur = 0
      while time <= endTime:
        
        if ei == len(events):
          ret.append(cur)
          cur = 0
          time += delta
          continue
          
        if events[ei] < time:
          ei += 1
        elif time + delta <= events[ei]:
          ret.append(cur)
          time += delta
          cur = 0
        else:
          assert time <= events[ei] < time + delta
          cur += 1
          ei += 1
      
      return ret
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tw = collections.defaultdict(list)
        self.duration = {'minute':60, 'hour':3600, 'day':86400 }

    def recordTweet(self, tweetName: str, time: int) -> None:
        if not self.tw[tweetName]:
            self.tw[tweetName].append(time)
        else:
            ind = bisect.bisect(self.tw[tweetName], time)
            self.tw[tweetName] = self.tw[tweetName][:ind] + [time] + self.tw[tweetName][ind:]
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        res = []
        
        q = self.tw[tweetName]
        
        s = startTime
        while s <= endTime:
            e = min(endTime, s + self.duration[freq]-1)            
            ind1 = bisect.bisect_left(q, s)
            ind2 = bisect.bisect_right(q, e, lo=ind1)
            res.append(ind2-ind1)
            s = e+1
            
        return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):    
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        new_data = [x for x in self.data[tweetName] if startTime <= x <= endTime]
        delta_data = [(x - startTime) // delta for x in new_data]
        n = (endTime - startTime) // delta + 1
        res = [len([x for x in delta_data if x == i]) for i in range(n)]
        return res
        
        
        
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res        

        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # start = startTime
        # res = []
        # self.data[tweetName].sort()
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime): 
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        new_data = [x for x in self.data[tweetName] if startTime <= x <= endTime]
        delta_data = [(x - startTime) // delta for x in new_data]
        n = (endTime - startTime) // delta + 1
        res = [len([x for x in delta_data if x == i]) for i in range(n)]
        return res
        
        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # new_data = [x for x in self.data[tweetName] if startTime <= x <= endTime]
        # delta_data = [(x - startTime) // delta for x in new_data]
        # n = (endTime - startTime) // delta + 1
        # res = [len([x for x in delta_data if x == i]) for i in range(n)]
        # return res
        
        
        
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res        

        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # start = startTime
        # res = []
        # self.data[tweetName].sort()
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
# approach 1:
# - record tweets organized by tweet name
# - compute freqs on demand
  
  def __init__(self):
    self.tweets = {} # tweetName: {time: count}

  def recordTweet(self, tweetName: str, time: int) -> None:
    self.tweets.setdefault(tweetName, {}).setdefault(time, 0)
    self.tweets[tweetName][time] += 1

  def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
    eligible = []
    
    for (time, count) in list(self.tweets.get(tweetName, {}).items()):
      if startTime <= time <= endTime:
        eligible.append((time, count))
    
    if 'minute' == freq:
      samples = 60
    elif 'hour' == freq:
      samples = 3600
    elif 'day' == freq:
      samples = 86400
    else:
      raise RuntimeError(freq)
      
    num_results = 1 + ((endTime - startTime) // samples)
    results = [0] * num_results
    
    for (time, count) in eligible:
      offset = (time - startTime)
      if 'minute' == freq:
        offset //= 60
      elif 'hour' == freq:
        offset //= 3600
      elif 'day' == freq:
        offset //= 86400
      results[offset] += count
    return results
  
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict

class TweetCounts:
    def __init__(self):
        self.data = defaultdict(list)
        
    def recordTweet(self, tweetName, time):
        self.data[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime): 
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        new_data = [x for x in self.data[tweetName] if startTime <= x <= endTime]
        delta_data = [(x - startTime) // delta for x in new_data]
        n = (endTime - startTime) // delta + 1
        res = [len([x for x in delta_data if x == i]) for i in range(n)]
        return res
        
        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # start = startTime
        # res = []
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     start += delta
        # return res
        
        # delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        # start = startTime
        # res = []
        # self.data[tweetName].sort()
        # while start <= endTime:
        #     end = min(start + delta, endTime + 1)
        #     res.append(len([x for x in self.data[tweetName] if start <= x < end]))
        #     # res.append(bisect_left(self.data[tweetName], end) - bisect_left(self.data[tweetName], start))
        #     start += delta
        # return res

# class TweetCounts:
#     def __init__(self):
#         self.data = defaultdict(list)
        
#     def recordTweet(self, tweetName, time):
#         bisect.insort(self.data[tweetName], time)
        
#     def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.data[tweetName], j) - bisect_left(self.data[tweetName], i))
#             i += delta
#         return res


# from collections import defaultdict
# class TweetCounts:

#     def __init__(self):
#         self.a = defaultdict(list)
        

#     def recordTweet(self, tweetName: str, time: int) -> None:
#         bisect.insort(self.a[tweetName], time)
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
#         i = startTime
#         res = []
#         while i <= endTime:
#             j = min(i + delta, endTime + 1)
#             res.append(bisect_left(self.a[tweetName], j) - bisect_left(self.a[tweetName], i))
#             i += delta
#         return res
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.dict = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        if(tweetName not in self.dict):
            self.dict[tweetName] = [time]
        else:
            self.dict[tweetName].append(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        times = self.dict[tweetName]
        
        size = 0 
        secs = 0
        
        if(freq == 'minute'):
            secs = 60
            size = (endTime - startTime) / 60 + 1
        if(freq == 'hour'):
            secs = 3600
            size = (endTime - startTime) / 3600 + 1
        if(freq == 'day'):
            secs = 86400
            size = (endTime - startTime) / 86400 + 1
                
        r = [0] * int(size)
        
        for i in times:
            if(startTime <= i and i <= endTime):
                index = int((i-startTime)/secs)
                r[index] += 1

        return r

class TweetCounts:

    def __init__(self):
        self.lookup = collections.defaultdict(list)
        self.convert = {'minute': 60, 'hour':3600, 'day': 86400}
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        self.lookup[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        seconds = self.convert[freq]
        ans = [0] * ((endTime-startTime)//seconds+1)
        for time in self.lookup[tweetName]:
            if startTime <= time <= endTime:
                ans[(time-startTime)//seconds] += 1
                
        return ans
                    
            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    MAP = {
            'minute': 60,
            'hour': 60 * 60,
            'day': 24 * 60 * 60
            }

    def __init__(self):
        self.data = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.data[tweetName].append(time)
        self.data[tweetName].sort()

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        data = self.data[tweetName]
        index = 0

        while index < len(data) and data[index] < startTime:
            index += 1

        ans = []
        tmp = 0
        k = 0
        delta = self.MAP[freq]
        while startTime + k * delta <= endTime:
            end = min(startTime + delta * (k + 1), endTime + 1)
            if index >= len(data) or data[index] >= end:
                ans.append(tmp)
                tmp = 0
                k += 1
            else:
                tmp += 1
                index += 1
        return ans

from bisect import insort, bisect_left, bisect_right
from math import ceil

class TweetCounts:

    def __init__(self):
        self.tweets={}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = []
        insort(self.tweets[tweetName], time)
        
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        entry = self.tweets[tweetName]
        diff = endTime - startTime
        factor = 86400
        if freq == 'minute':
            factor = 60
        elif freq == 'hour':
            factor = 3600
        buckets = math.ceil((diff + 1) / factor)
        ans = [0]*buckets
        start = bisect_left(entry, startTime)
        end = bisect_right(entry, endTime)
        for i in range(start, end):
            time = entry[i]
            d = (time - startTime) // factor
            ans[d] += 1
        return ans
        '''ans=[]
        if freq=='minute':
            q=endTime//60
            p=startTime//60
            for j in range(p,q+1):
                count=0
                for i in range(len(self.tname)):
                    if self.tname[i]==tweetName:
                        if startTime+j*60<=self.t[i]<min(startTime+(j+1)*60,endTime+1):
                            count+=1
                ans.append(count)
        elif freq=='hour':
            q=endTime//3600
            p=startTime//3600
            for j in range(p,q+1):
                count=0
                for i in range(len(self.tname)):
                    if self.tname[i]==tweetName:
                        if startTime+j*3600<=self.t[i]<min(startTime+(j+1)*3600,endTime+1):
                            count+=1
                ans.append(count)
        else:
            q=endTime//(3600*24)
            p=startTime//(3600*24)
            for j in range(p,q+1):
                count=0
                for i in range(len(self.tname)):
                    if self.tname[i]==tweetName:
                        if startTime+j*(24*3600)<=self.t[i]<min(startTime+(j+1)*(3600*24),endTime+1):
                            count+=1
                ans.append(count)
        return ans'''
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from sortedcontainers import SortedList

class TweetCounts:
    freq_seconds = {
        'minute': 60,
        'hour': 3600,
        'day': 86400,
    }
    
    def __init__(self):
        self.tweets: Dict[str, List[int]] = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweets:
            self.tweets[tweetName] = SortedList()
        self.tweets[tweetName].add(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        interval = self.freq_seconds[freq]
        counts = []
        times = self.tweets.get(tweetName, [])
        bucket_start = startTime
        index_start = times.bisect_left(bucket_start)
        while bucket_start <= endTime:
            bucket_end = min(bucket_start + interval, endTime + 1)
            index_end = times.bisect_left(bucket_end)
            counts.append(index_end - index_start)
            bucket_start = bucket_end
            index_start = index_end
        return counts


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.d={}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if(tweetName in self.d):
            self.d[tweetName].append(time)
        else:
            self.d[tweetName]=[time]
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if(tweetName not in self.d):
            return [0]
        a=self.d[tweetName]
        if(freq==\"minute\"):
            c=[0 for i in range(1+((endTime-startTime)//60))]
            for i in a:
                if(i>=startTime)and(i<=endTime):
                    c[(i-startTime)//60]+=1
            return c
        if(freq==\"hour\"):
            c=[0 for i in range(1+((endTime-startTime)//3600))]
            for i in a:
                if(i>=startTime)and(i<=endTime):
                    c[(i-startTime)//3600]+=1
            return c
        if(freq==\"day\"):
            c=[0 for i in range(1+((endTime-startTime)//86400))]
            for i in a:
                if(i>=startTime)and(i<=endTime):
                    c[(i-startTime)//86400]+=1
            return c
            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.secondsMap = {
\t\t\t\"day\": 86400,
\t\t\t\"hour\": 3600,
\t\t\t\"minute\": 60
\t\t}
        self.tweets = {}
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.tweets:
            self.tweets[tweetName].append(time)
        else:
            self.tweets[tweetName] = [time]

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        seconds = self.secondsMap[freq]
        bucket_size = int((endTime - startTime)/seconds)+1
        buckets = [0]*bucket_size
        if tweetName not in self.tweets:
            return []
        else:
            for t in self.tweets[tweetName]:
                if t >= startTime and t<= endTime:
                    bucket_index = int((t - startTime)/seconds)
                    buckets[bucket_index] += 1
        return buckets
                    
                
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from typing import List
from sortedcontainers import SortedList
from collections import defaultdict

SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 60*SECONDS_PER_MINUTE
SECONDS_PER_DAY = 24*SECONDS_PER_HOUR
INTERVAL_LENGTH = {
    'minute': SECONDS_PER_MINUTE,
    'hour': SECONDS_PER_HOUR,
    'day': SECONDS_PER_DAY,
}

class TweetCounts:
    def __init__(self):
        self.tweets = defaultdict(SortedList)

    def recordTweet(self, tweetName: str, time: int) -> None:
        # print(f'record {tweetName} at {time}')
        self.tweets[tweetName].add(time)
        # print(f'tweets[tweetName]: {self.tweets[tweetName]}')

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        # print(f'freq={freq} tweetName={tweetName} startTime={startTime} endTime={endTime}')

        if freq not in INTERVAL_LENGTH:
            raise Exception(f'Expected freq to be one of {INTERVAL_LENGTH.keys()}, got {freq} instead')

        if tweetName not in self.tweets:
            raise Exception(f'Unknown tweet: {tweetName}')

        intervalLength = INTERVAL_LENGTH[freq]
        numIntervals = (endTime - startTime + intervalLength) // intervalLength

        counts = []
        for i in range(numIntervals):
            intervalStart = startTime + i*intervalLength
            intervalEnd = min(intervalStart + intervalLength, endTime + 1)
            matchingTimes = self.tweets[tweetName].irange(minimum=intervalStart, maximum=intervalEnd, inclusive=(True, False))
            counts.append(len(list(matchingTimes)))

        # print(f'counts: {counts}')
        return counts


import bisect

class TweetCounts:

    def __init__(self):
        self.td = dict()
        self.incrDict = {'minute':60,'hour':60*60,'day':24*60*60}

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.td[tweetName] = self.td.get(tweetName,list())
        self.td[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if tweetName not in self.td:
            return []
        tl = sorted(self.td.get(tweetName,list()))
        si = bisect.bisect_left(tl,startTime)
        ei = bisect.bisect_right(tl,endTime)
        incr = self.incrDict[freq]
        res = []
        for i in range(math.ceil((endTime-startTime+1)/incr)):
            et = startTime + (i+1)*incr
            ind = bisect.bisect_right(tl,et-1,si,ei)
            res.append(ind-si)
            si = ind
        
        return res
            
        
        
        
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


import numpy as np

class TweetCounts:

    def __init__(self):
        self.tweets = {}
        self.tweets_sorted = {}
        self.intervals = {\"minute\": 60, \"hour\": 3600, \"day\": 3600 * 24}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        if not tweetName in self.tweets: 
            self.tweets[tweetName] = np.array([])
        
        self.tweets_sorted[tweetName] = False
        self.tweets[tweetName] = np.append(self.tweets[tweetName], [time])
        # print(self.tweets[tweetName])
        

#     def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
#         interval = self.intervals[freq]
#         # bins = [[i*interval, (i+1)*interval] for i in range(int(np.ceil((endTime - startTime) / interval)))]
#         bins = []
#         t_start=startTime
#         while t_start <= endTime:
#             bins.append([t_start, t_start + interval])
#             t_start += interval
        
#         bins[-1][1] = endTime + 1
        
#         # h,e = np.histogram(self.tweets[tweetName], bins=interval, range=(startTime, endTime))
#         count = np.zeros(len(bins), dtype=np.int)
        
#         for t in self.tweets[tweetName]:
#             for bi, b in enumerate(bins):
#                 if b[0]<= t < b[1]:
#                     count[bi] += 1
                    
#         return h 

    
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        interval = self.intervals[freq]
        # bins = [[i*interval, (i+1)*interval] for i in range(int(np.ceil((endTime - startTime) / interval)))]
        bins = []
        t_start=startTime
        while t_start <= endTime:
            bins.append([t_start, t_start + interval])
            t_start += interval
        
        bins[-1][1] = endTime + 1
        count = np.zeros(len(bins), dtype=np.int)
        
        if not self.tweets_sorted[tweetName]: self.tweets[tweetName].sort()
        
        e_end = startTime + interval
        
        ## Find borders
        i_start, i_end = np.searchsorted(self.tweets[tweetName], v=[startTime-1, endTime+1], side=\"right\")
        int_i = 0
        for t in self.tweets[tweetName][i_start:i_end]:
            while t >= e_end and t <= endTime:
                int_i += 1
                e_end += interval
            
            if t <= endTime: count[int_i] += 1       
                    
        return count    


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.arr = collections.defaultdict(lambda: [])
        self.mapping = {\"hour\": 3600, \"minute\":60, \"day\":3600*24}

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.arr[tweetName], time)
            
        

    def getTweetCountsPerFrequency(self, freq: str, t: str, start: int, end: int) -> List[int]:
        ans = []
        interval = self.mapping[freq]
        while start<=end:
            ans.append(bisect.bisect_left(self.arr[t], min(end+1, start+interval)) - bisect.bisect_left(self.arr[t], start))
            start += interval
        return ans
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

freq_map = {\"minute\": 60, \"hour\": 3600, \"day\": 24*3600}
class TweetCounts:
    def __init__(self):
        self.tweet_dict = {}

    def recordTweet(self, tweetName, time):
        if tweetName not in self.tweet_dict:
            self.tweet_dict[tweetName] = []
        self.tweet_dict[tweetName].append(time)
        
    def getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
        if tweetName not in self.tweet_dict:
            return None
        intervals = (-startTime + endTime)//freq_map[freq] + 1
        
        output = [0]*(intervals)
        for elem in sorted(self.tweet_dict[tweetName]):
            if elem >= startTime and elem <= endTime:
                output[(elem - startTime)//freq_map[freq]] += 1
            if elem > endTime:
                break
        return output

        # Your TweetCounts object will be instantiated and called as such:
        # obj = TweetCounts()
        # obj.recordTweet(tweetName,time)
        # param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict, deque
import bisect

class TweetCounts:

    def __init__(self):
        self._deltas = {
            'minute': 60,
            'hour': 60*60,
            'day':60*60*24
        }
        self._tweets = defaultdict(deque)
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort_left(self._tweets[tweetName], time)
        
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        tweet_times = self._tweets[tweetName]
        left = 0
        right = len(tweet_times)
        while left < right:
            mid = (left + right) // 2
            if tweet_times[mid] >= startTime:
                right = mid
            else:
                left = mid + 1
        output = [0]
        interval = self._deltas[freq]
        period_start = startTime
        while left < len(tweet_times) and tweet_times[left] <= endTime:
            if tweet_times[left] < period_start + interval:
                output[-1] += 1
                left += 1
            else:
                period_start += interval
                output.append(0)
        for _ in range((endTime - period_start ) // interval):
            output.append(0)
        return output
    
    


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    
    FREQUENCE = {
        'minute' : 60,
        'hour' : 3600,
        'day' : 24*3600,
    }

    def __init__(self):
        self.store = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        
        if tweetName not in self.store:
            self.store[tweetName] = {}
        if time not in self.store[tweetName]:
            self.store[tweetName][time]=0
            
        self.store[tweetName][time]+=1


    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        if tweetName not in self.store:
            return []
        
        delta = TweetCounts.FREQUENCE[freq]
        
        keys = list(self.store.get(tweetName).keys())
        keys = sorted(keys)
        
        start =  bisect.bisect_left(keys, startTime)
        end =  bisect.bisect_right(keys, endTime)
        
        num_intervals = (endTime - startTime) // delta + 1
        
        result = [0] * num_intervals
        
                    
        for t1 in range(start-1, end+1):            
            if t1 < 0:
                continue
            if t1 >= len(keys):
                break
                
            t = keys[t1]
            
            if t<startTime or t>endTime:
                continue
            
            index = (t - startTime) // delta
            result[index] +=  self.store.get(tweetName).get(t)
        
        return result


class TweetCounts:

    def __init__(self):

        self.second = defaultdict(list)


    def recordTweet(self, tweetName: str, time: int) -> None:

        
        bisect.insort(self.second[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq == \"minute\":
            step =  60
        elif freq == \"hour\":
            step = 3600
        else:
            step = 3600 * 24
            
        ans = []
        l = self.second[tweetName]
        while(startTime <= endTime):
            start, end = startTime, min(startTime + step-1, endTime)
            left, right = bisect.bisect_left(l, start), bisect.bisect_right(l, end)
            ans.append(right-left)
            startTime += step 
        return ans
        
    

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict
class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        tweet_ts = self.tweets[tweetName]
        if not len(tweet_ts):
            return []
        diff = endTime - startTime
        seconds_in_interval = 0
        if freq == \"minute\":
            seconds_in_interval = 60
        elif freq == \"hour\":
            seconds_in_interval = 3600
        else:
            seconds_in_interval = 3600 * 24
        output = [0] * ((diff//seconds_in_interval) + 1)
        for ts in tweet_ts:
            if endTime >= ts >= startTime:
                output[(ts - startTime)//seconds_in_interval] += 1
        return output
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

# similiar : design-log-storage-system-635
class TweetCounts:

    def __init__(self):
        self.__records = collections.defaultdict(list)
        self.__lookup = {\"minute\": 60, \"hour\": 3600, \"day\": 86400}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.__records[tweetName].append(time)



    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = self.__lookup[freq]
        result = [0] * ((endTime - startTime) // delta + 1)
        for t in self.__records[tweetName]:
            if startTime <= t <= endTime:
                result[(t - startTime) // delta] += 1
        return result
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweets = collections.defaultdict(list)
    

    def __bs(self, arr, val):
        lo, hi = 0, len(arr)

        while lo < hi:
            mid = (lo + hi) // 2
            
            if arr[mid] >= val:
                hi = mid
            else:
                lo = mid + 1
        return lo

    def recordTweet(self, tweetName: str, time: int) -> None:
        idx = self.__bs(self.tweets[tweetName], time)
        self.tweets[tweetName].insert(idx, time)
 

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
        i = startTime
        arr = self.tweets[tweetName]
        result = []
        while i <= endTime:
            j = min(i + delta, endTime + 1)
            result.append(self.__bs(arr, j) - self.__bs(arr, i))
            i += delta
        return result

            


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.data = defaultdict(list)

    def recordTweet(self, tweetName: str, time: int) -> None:
        self.data[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if freq[0]=='m':
            ans = [0]*((endTime-startTime)//60 +1)
            for x in self.data[tweetName]:
                if startTime<=x<=endTime:
                    a = (x-startTime)//60
                    ans[a]+=1
            return ans
            
        elif freq[0]=='h':
            ans = [0]*((endTime-startTime)//3600 +1)
            for x in self.data[tweetName]:
                if startTime<=x<=endTime:
                    a = (x-startTime)//3600
                    ans[a]+=1
            return ans
        else:
            ans = [0]*((endTime-startTime)//86400 +1)
            for x in self.data[tweetName]:
                if startTime<=x<=endTime:
                    a = (x-startTime)//86400
                    ans[a]+=1
            return ans


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


import collections


class TweetCounts(object):

\tdef __init__(self):
\t\tself.tweets = collections.defaultdict(list)

\tdef recordTweet(self, tweetName, time):
\t\t\"\"\"
\t\t:type tweetName: str
\t\t:type time: int
\t\t:rtype: None
\t\t\"\"\"
\t\tindex = self.binary_search(tweetName, time)
\t\tself.tweets[tweetName].insert(index,  time)


\tdef getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
\t\t\"\"\"
\t\t:type freq: str
\t\t:type tweetName: str
\t\t:type startTime: int
\t\t:type endTime: int
\t\t:rtype: List[int]
\t\t\"\"\"
\t\tdelta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
\t\ti = startTime
\t\tres = []
\t\twhile i <= endTime:
\t\t\tj = min(i + delta, endTime + 1)
\t\t\tres.append(self.binary_search(tweetName, j) - self.binary_search(tweetName, i))
\t\t\ti += delta

\t\treturn res


\tdef binary_search(self, tweetName, time):
\t\tcur_list = self.tweets[tweetName]
\t\tl = 0
\t\tr = len(cur_list) 
\t\twhile l < r:
\t\t\tmid = (l+r) // 2
\t\t\tif cur_list[mid] < time:
\t\t\t\tl = mid + 1
\t\t\telse:
\t\t\t\tr = mid

\t\treturn l


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.tweets = {}
        
        self.delta = {\"minute\": 60, \"hour\": 3600, \"day\": 86400}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.tweets:
            self.tweets[tweetName].append(time)
        else:
            self.tweets[tweetName] = [time]
        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        
        times = sorted(filter(lambda t: startTime <= t <= endTime, self.tweets.get(tweetName, [])))
        
        delta = self.delta[freq]
        
        ranges = [[startTime + delta*i, startTime + delta*(i+1)-1] \\
                  for i in range((endTime - startTime) // delta)]
        
        ranges.append([startTime + delta*len(ranges), endTime])
        
        counts = {tuple(k): 0 for k in ranges}
        
        i = 0
        for n in times:
            while n > ranges[i][1]:
                i += 1
                
            counts[tuple(ranges[i])] += 1
            
        
        return counts.values()
            
                       
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

from collections import defaultdict 
import bisect
class TweetCounts:
    
    freq_map = {'minute': 60, 'hour': 3600, 'day': 3600 * 24 }
    
    def __init__(self):
        # map of tweetName => [] ordered list of frequencies
        self.tweet_map = defaultdict(list)
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.tweet_map[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        # print(f'getTweetCountsPerFrequency: {startTime}: {endTime}: {freq}')
        
        interval_length = TweetCounts.freq_map[freq]
        # print(self.tweet_map[tweetName])
        starting_index = bisect.bisect_left(self.tweet_map[tweetName],startTime)
        
        res = []
        curr_index = starting_index
        current_interval_start = startTime
        current_interval_end = min(current_interval_start + interval_length - 1, endTime)  # inclusive
        current_interval_count = 0
        while current_interval_end <= endTime: 
            # print(f'{current_interval_start} - {current_interval_end}: count:{current_interval_count} ')
            if curr_index < len(self.tweet_map[tweetName]):
                # have not run out of timestamps 
                if self.tweet_map[tweetName][curr_index] <= current_interval_end: 
                    # current tweet is within the current interval
                    current_interval_count +=1
                    curr_index += 1
                elif current_interval_end!= endTime:
                    # push to next interval
                    current_interval_start += interval_length
                    current_interval_end = min(current_interval_end + interval_length, endTime)
                    res.append(current_interval_count)
                    current_interval_count = 0
                else:
                    res.append(current_interval_count)
                    break
            elif current_interval_end!= endTime:
                # already went through all timestamps. go to the next time interval 
                current_interval_start += interval_length
                current_interval_end  = min(current_interval_end + interval_length, endTime)
                res.append(current_interval_count)
                current_interval_count = 0
            else: 
                res.append(current_interval_count)
                break
                    
        return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetNode:
    def __init__(self, time, count = 1):
        self.time       = time
        self._count     = count
        self.left_node  = None
        self.right_node = None
    
    def add_time(self, time):
        if self.time > time:
            if self.left_node is None:
                self.left_node = TweetNode(time)
            else:
                self.left_node.add_time(time)
        elif self.time < time:
            if self.right_node is None:
                self.right_node = TweetNode(time)
            else:
                self.right_node.add_time(time)
        else:
            self._count += 1
    
    def count(self, start_time, end_time):
        if self.time > end_time:
            return (self.left_node and self.left_node.count(start_time, end_time) or 0)
        elif self.time < start_time:
            return (self.right_node and self.right_node.count(start_time, end_time) or 0)
        else:
            return (
                self._count
                + (self.left_node  and self.left_node.count(start_time, end_time)  or 0)
                + (self.right_node and self.right_node.count(start_time, end_time) or 0)
            )
        
    def __str__(self):
        return '{ \"count\" : %s, \"time\" : %s, \"left\" : %s, \"right\" : %s }' % (self._count, self.time, str(self.left_node), str(self.right_node))
    
    def __repr__(self):
        return str(self)
            
class TweetCounts:

    def __init__(self):
        self.tweets = dict()

    def recordTweet(self, tweet_name: str, time: int) -> None:
        if tweet_name not in self.tweets:
            self.tweets[tweet_name] = TweetNode(time)
        else:
            self.tweets[tweet_name].add_time(time)

    def getTweetCountsPerFrequency(self, freq: str, tweet_name: str, start_time: int, end_time: int) -> List[int]:
        if tweet_name in self.tweets:
            if freq   == \"minute\":
                delta = 60
            elif freq == \"hour\":
                delta = 60 * 60
            elif freq == \"day\":
                delta = 60 * 60 * 24
            else:
                raise NotImplemented(\"The set frequency is not implemented.\")
            return [
                self.tweets[tweet_name].count(st, ((st + delta - 1) if (st + delta - 1) < end_time else end_time)) for st in range(start_time, end_time + 1, delta)
            ]
        else:
            return 0

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.data = collections.defaultdict(dict)


    def recordTweet(self, tweetName: str, time: int) -> None:
        if time not in self.data[tweetName]:
            self.data[tweetName][time] = 1
        else: self.data[tweetName][time] += 1

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = [60, 60*60, 60*60*24]
        if freq == 'minute':
            t = delta[0]
        elif freq == 'hour':
            t = delta[1]
        else: t = delta[2]
        res = [0]*((endTime - startTime)//t+1)
        i = 0
        data = self.data[tweetName]
        for time in sorted(data.keys()):
            if startTime <= time <= endTime: 
                res[(time - startTime)//t] += data[time]
        return res



# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:
    STEP_DICT = {
        \"minute\": 60,
        \"hour\": 60 * 60,
        \"day\": 60 * 60 * 24,
    }

    def __init__(self):
        self.tweet_map = defaultdict(list)

    def recordTweet(self, tweet_name: str, t: int) -> None:
        self.tweet_map[tweet_name].append(t)

    def getTweetCountsPerFrequency(self, freq: str, tweet_name: str, start: int, stop: int) -> List[int]:
        result = []

        if tweet_name not in self.tweet_map:
            return result

        step = self.STEP_DICT[freq]

        tweet_times = sorted([t for t in self.tweet_map[tweet_name] if start <= t <= stop])
        tweet_times_intervals = [(t - start) // step + 1 for t in tweet_times]
        tweet_times_intervals_dict = defaultdict(int)
        for interval in tweet_times_intervals:
            tweet_times_intervals_dict[interval] += 1

        interval = 1
        while start <= stop:
            result.append(tweet_times_intervals_dict.get(interval, 0))
            interval += 1
            start += step

        return result


class TweetCounts:

    def __init__(self):
        self.tweets = defaultdict(list)
        self.mapping = {'minute':60,'hour':3600,'day':86400}
        
    def binary_search(self,left,right,key,array,type):
        while left<=right:
            mid = left + (right-left)//2
            if array[mid]>=key:
                right=mid-1
            else:
                left = mid+1
        return left if type=='S' else right        
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        self.tweets[tweetName].append(time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        self.tweets[tweetName].sort()
        tweetcounts = self.tweets[tweetName]
        intervals = []
        while startTime<endTime+1:
            #Binary Search to find the tweets 
            startindex = self.binary_search(0,len(tweetcounts)-1,startTime,tweetcounts,'S')
            findval = min(startTime+self.mapping[freq],endTime+1)
            endindex = self.binary_search(0,len(tweetcounts)-1,findval,tweetcounts,'E')
            intervals.append(endindex-startindex+1)
            startTime+=self.mapping[freq]
        return intervals
# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.tweet2time = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.tweet2time:
            self.tweet2time[tweetName] = [time]
        else:
            arr = self.tweet2time[tweetName]
            index = self.binary_search(arr, time)
            arr.insert(index, time)
            
            

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        if tweetName not in self.tweet2time:
            return []
        
        arr = self.tweet2time[tweetName]
        
        if freq == 'minute':
            interval = 60
        elif freq == 'hour':
            interval = 3600
        else:
            interval = 3600 * 60
        
        
        time = startTime
        result = []
        while time <= endTime:
            end_time = time + interval
            start_index = self.binary_search(arr, time)
            end_index = self.binary_search(arr, min(end_time, endTime + 1))
            # if start_index == end_index and arr[-1] == time:
                # end_index += 1
            
            result.append(end_index - start_index)
            
            time = end_time
            
        return result    
    
    def binary_search(self, arr, num):
        # if num <= arr[0]:
            # return 0
        # elif num >= arr[-1]:
            # return len(arr)
        # elif num > arr[-1]:
            # return len(arr) + 1
        # else:
        left = 0
        right = len(arr)

        while left < right:
            mid = left + (right - left) // 2
            if arr[mid] > num:
                right = mid
            elif arr[mid] < num:
                left = mid + 1
            else:
                return mid

        return left    
        


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


import collections


class TweetCounts(object):

\tdef __init__(self):
\t\tself.tweets = collections.defaultdict(list)

\tdef recordTweet(self, tweetName, time):
\t\tself.tweets[tweetName].insert(self.binary_search(tweetName, time),  time)


\tdef getTweetCountsPerFrequency(self, freq, tweetName, startTime, endTime):
\t\tdelta = 60 if freq == 'minute' else 3600 if freq == 'hour' else 86400
\t\ti = startTime
\t\tres = []
\t\twhile i <= endTime:
\t\t\tj = min(i + delta, endTime + 1)
\t\t\tres.append(self.binary_search(tweetName, j) - self.binary_search(tweetName, i))
\t\t\ti += delta

\t\treturn res


\tdef binary_search(self, tweetName, time):
\t\tcur_list = self.tweets[tweetName]
\t\tl = 0
\t\tr = len(cur_list) 
\t\twhile l < r:
\t\t\tmid = (l+r) // 2
\t\t\tif cur_list[mid] < time:
\t\t\t\tl = mid + 1
\t\t\telse:
\t\t\t\tr = mid

\t\treturn l

class TweetCounts:

    def __init__(self):
        self.tweetDict = {}
    
    def insertAt(self, tN, x):
        l = 0
        r = len(self.tweetDict[tN]) - 1
        if x < self.tweetDict[tN][l]:
            return 0
        if x > self.tweetDict[tN][r]:
            return r + 1
        while r > l:
            m = (r + l) // 2
            if self.tweetDict[tN][m] < x:
                l = m+ 1
            else:
                r = m
        return l
    
    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.tweetDict:
            self.tweetDict[tweetName].insert(self.insertAt(tweetName, time), time)
        else:
            self.tweetDict[tweetName] = [time]

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        ans = []
        if freq == 'minute':
            delta = 60
        elif freq == 'hour':
            delta = 3600
        else:
            delta = 86400
        total = (endTime - startTime)//delta
        if (endTime - startTime)%delta > 0:
            total += 1
        n = 0
        for t in range(startTime, endTime+1, delta):
            t0 = t
            t1 = min(t+delta, endTime+1)
            i0 = self.insertAt(tweetName, t0)
            # print(t0, t1)
            if i0 == len(self.tweetDict[tweetName]):
                ans += [0]* (total - n)
                # ans.append(0)
                return ans
            i1 = self.insertAt(tweetName, t1)
            if i1 == len(self.tweetDict[tweetName]):
                ans.append(i1 - i0)
                ans += [0]* (total - n - 1)
                return ans
            n += 1
            ans.append(i1 - i0)
        return ans
            

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


from collections import defaultdict 
import bisect
class TweetCounts:
    
    freq_map = {'minute': 60, 'hour': 3600, 'day': 3600 * 24 }
    
    def __init__(self):
        # map of tweetName => [] ordered list of frequencies
        self.tweet_map = defaultdict(list)
        
    def recordTweet(self, tweetName: str, time: int) -> None:
        bisect.insort(self.tweet_map[tweetName], time)

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        # print(f'getTweetCountsPerFrequency: {startTime}: {endTime}: {freq}')
        
        interval_length = TweetCounts.freq_map[freq]
        # print(self.tweet_map[tweetName])
        starting_index = bisect.bisect_left(self.tweet_map[tweetName],startTime)
        
        res = []
        curr_index = starting_index
        current_interval_start = startTime
        current_interval_end = min(current_interval_start + interval_length - 1, endTime)  # inclusive
        current_interval_count = 0
        while current_interval_end <= endTime: 
            # print(f'{current_interval_start} - {current_interval_end}: count:{current_interval_count} ')
            if curr_index < len(self.tweet_map[tweetName]):
                # have not run out of timestamps 
                if self.tweet_map[tweetName][curr_index] <= current_interval_end: 
                    # current tweet is within the current interval
                    current_interval_count +=1
                    curr_index += 1
                    continue
            if current_interval_end!= endTime:
                # already went through all timestamps. go to the next time interval 
                current_interval_start += interval_length
                current_interval_end  = min(current_interval_end + interval_length, endTime)
                res.append(current_interval_count)
                current_interval_count = 0
            else: 
                res.append(current_interval_count)
                break
                    
        return res


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.d = {}

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.d:
            self.d[tweetName] = []
        arr = self.d[tweetName]
        i = len(arr)-1
        while i >= 0 and arr[i] > time:
            i -= 1
        self.d[tweetName] = arr[:i+1] + [time] + arr[i+1:]
        # assert self.d[tweetName] == sorted(self.d[tweetName])

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        # print(freq, tweetName, startTime, endTime, self.d)
        arr = self.d.get(tweetName, [])
        r = []
        j = 0
        step = (1 if freq == \"second\" else 
               60 if freq == \"minute\" else 
               60*60 if freq == \"hour\" else 
                60*60*24)
        while j < len(arr) and arr[j] < startTime:
            j += 1
        for i in range(startTime, endTime+1, step):
            r.append(0)
            while j < len(arr) and arr[j] <= min(i+step-1, endTime):
                j += 1
                r[-1] += 1
        return r


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        self.tweetDict = {}
    
    def insertAt(self, tN, x):
        l = 0
        r = len(self.tweetDict[tN]) - 1
        if x < self.tweetDict[tN][l]:
            return 0
        if x > self.tweetDict[tN][r]:
            return r + 1
        while r > l:
            m = (r + l) // 2
            if self.tweetDict[tN][m] < x:
                l = m+ 1
            else:
                r = m
        return l
    
    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName in self.tweetDict:
            self.tweetDict[tweetName].insert(self.insertAt(tweetName, time), time)
        else:
            self.tweetDict[tweetName] = [time]

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        ans = []
        if freq == 'minute':
            delta = 60
        elif freq == 'hour':
            delta = 3600
        else:
            delta = 86400
        total = (endTime - startTime)//delta
        if (endTime - startTime)%delta > 0:
            total += 1
        n = 0
        for t in range(startTime, endTime+1, delta):
            t0 = t
            t1 = min(t+delta, endTime+1)
            i0 = self.insertAt(tweetName, t0)
            print((t0, t1))
            if i0 == len(self.tweetDict[tweetName]):
                ans += [0]* (total - n)
                # ans.append(0)
                return ans
            i1 = self.insertAt(tweetName, t1)
            if i1 == len(self.tweetDict[tweetName]):
                ans.append(i1 - i0)
                ans += [0]* (total - n - 1)
                return ans
            n += 1
            ans.append(i1 - i0)
        return ans
            

# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        from bisect import bisect_left, bisect_right
        from functools import lru_cache
        self.tweets = {}
        return


    def recordTweet(self, tweetName: str, time: int) -> None:
        tn, seconds = tweetName, time
        if tn not in self.tweets: self.tweets[tn] = Counter()
        self.tweets[tn] += Counter(dict([(seconds, 1)]))
        return


    def quantize(self, per_second_tweet_counter, valid_times, scale):
        t = [((timekey-self.st)//scale, per_second_tweet_counter[timekey]) 
             for timekey in valid_times]
        
        qcnts, qkeys = {}, []
        for tk, tc in t:
            if tk not in qcnts:
                qcnts[tk] = 0
                qkeys.append(tk)
            qcnts[tk] += tc

        #qkeys = list(qcnts.keys())
        n = (self.et - self.st + 1) // scale
        if (self.et - self.st + 1) % scale: n += 1
        res = [0] * (n)
        for tk in qkeys: res[tk] = qcnts[tk]
        return res

    @lru_cache
    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        M, H, D = 60, 60*60, 60*60*24
        tn, st, et = tweetName, startTime, endTime
        if tn not in self.tweets: return [0]
        self.st, self.et = st, et

        per_second_tweet_counter = self.tweets[tn]
        valid_times = [timekey for timekey in per_second_tweet_counter
                       if st <= timekey <= et]

        if freq == 'minute': return self.quantize(per_second_tweet_counter, valid_times, M)
        if freq == 'hour': return self.quantize(per_second_tweet_counter, valid_times, H)
        if freq == 'day': return self.quantize(per_second_tweet_counter, valid_times, D)
        
        return [0]


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        from bisect import bisect_left, bisect_right
        from functools import lru_cache
        self.tweets = {}
        return


    def recordTweet(self, tweetName: str, time: int) -> None:
        tn, seconds = tweetName, time
        if tn not in self.tweets: self.tweets[tn] = Counter()
        self.tweets[tn] += Counter(dict([(seconds, 1)]))
        return


    def quantize(self, per_second_tweet_counter, valid_times, scale):
        t = [((timekey-self.st)//scale, per_second_tweet_counter[timekey]) 
             for timekey in valid_times]
        
        qcnts, qkeys = {}, []
        for tk, tc in t:
            if tk not in qcnts:
                qcnts[tk] = 0
                qkeys.append(tk)
            qcnts[tk] += tc

        qkeys = list(qcnts.keys())
        n = (self.et - self.st + 1) // scale
        if (self.et - self.st + 1) % scale: n += 1
        res = [0] * (n)
        for tk in qkeys: res[tk] = qcnts[tk]
        return res


    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        M, H, D = 60, 60*60, 60*60*24
        self.tn, self.st, self.et = tweetName, startTime, endTime
        if self.tn not in self.tweets: return [0]

        per_second_tweet_counter = self.tweets[self.tn]
        valid_times = [timekey for timekey in per_second_tweet_counter
                       if self.st <= timekey <= self.et]

        if freq == 'minute':
            return self.quantize(per_second_tweet_counter, valid_times, M)
        if freq == 'hour':
            return self.quantize(per_second_tweet_counter, valid_times, H)
        if freq == 'day':
            return self.quantize(per_second_tweet_counter, valid_times, D)
        
        return [0]


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)


class TweetCounts:

    def __init__(self):
        self.db = {}
        

    def recordTweet(self, tweetName: str, time: int) -> None:
        if tweetName not in self.db:
            self.db[tweetName] = [time]

        elif tweetName in self.db:
            idx = len(self.db[tweetName])

            for i in range(len(self.db[tweetName])):
                if self.db[tweetName][i] >= time:
                    idx = i
                    break


            self.db[tweetName].insert(idx, time)

        

    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        delta = 1

        if freq == \"minute\":
            # startTime *= 60
            # endTime *= 60
            delta *= 60

        elif freq == \"hour\":
            # startTime *= 60*60
            # endTime *= 60*60
            delta *= 60*60

        elif freq == \"day\":
            # startTime *= 60*60*12
            # endTime *= 60*60*12
            delta *= 60*60*12

        if tweetName not in self.db:
            # Would we instead want a list of zeroes.
            return [0]

        # delta -= 1
        
        start = startTime
        ans = []


        # Max val:
        maxTime = self.db[tweetName][-1]
        
        if startTime > maxTime:
    
            while start <= endTime:
                ans.append(0)

                start += delta
                
            return ans


        # Tweets
        tweets = self.db[tweetName]

        idx = 0

        while start > tweets[idx]:
            idx += 1

        # print(endTime)

        while start <= maxTime and start <= endTime:
            # print(start)
            tmp = 0

            while tweets[idx] <= endTime and start <= tweets[idx] < start+delta:

                tmp += 1

                if tweets[idx] == maxTime:
                    break

                idx += 1
                
            ans.append(tmp)
            start += delta
                
        while start <= endTime:
            ans.append(0)

            start += delta




        # Remove trailing zeroes

        return ans




# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)

class TweetCounts:

    def __init__(self):
        from bisect import bisect_left, bisect_right
        from functools import lru_cache
        self.tweets = {}
        self.cache = {}
        return


    def recordTweet(self, tweetName: str, time: int) -> None:
        tn, seconds = tweetName, time
        if tn not in self.tweets: self.tweets[tn] = Counter()
        self.tweets[tn] += Counter(dict([(seconds, 1)]))
        return


    def quantize(self, per_second_tweet_counter, valid_times, scale):
        t = [((timekey-self.st)//scale, per_second_tweet_counter[timekey]) 
             for timekey in valid_times]
        
        qcnts, qkeys = {}, []
        for tk, tc in t:
            if tk not in qcnts:
                qcnts[tk] = 0
                qkeys.append(tk)
            qcnts[tk] += tc

        n = (self.et - self.st + 1) // scale
        if (self.et - self.st + 1) % scale: n += 1
        res = [0] * (n)
        for tk in qkeys: res[tk] = qcnts[tk]
        return res


    def getTweetCountsPerFrequency(self, freq: str, tweetName: str, startTime: int, endTime: int) -> List[int]:
        M, H, D = 60, 60*60, 60*60*24
        self.tn, self.st, self.et = tweetName, startTime, endTime
        if self.tn not in self.tweets: return [0]

        per_second_tweet_counter = self.tweets[self.tn]

        key = (self.tn, self.st, self.et)
        if key in self.cache:
            valid_times = self.cache[key]
        else:
            valid_times = [timekey for timekey in per_second_tweet_counter
                           if self.st <= timekey <= self.et]
            
        if freq == 'minute':
            return self.quantize(per_second_tweet_counter, valid_times, M)
        if freq == 'hour':
            return self.quantize(per_second_tweet_counter, valid_times, H)
        if freq == 'day':
            return self.quantize(per_second_tweet_counter, valid_times, D)
        
        return [0]


# Your TweetCounts object will be instantiated and called as such:
# obj = TweetCounts()
# obj.recordTweet(tweetName,time)
# param_2 = obj.getTweetCountsPerFrequency(freq,tweetName,startTime,endTime)