1 00:00:00,090 --> 00:00:02,490 The following content is provided under a Creative 2 00:00:02,490 --> 00:00:04,030 Commons license. 3 00:00:04,030 --> 00:00:06,360 Your support will help MIT OpenCourseWare 4 00:00:06,360 --> 00:00:10,720 continue to offer high quality educational resources for free. 5 00:00:10,720 --> 00:00:13,320 To make a donation or view additional materials 6 00:00:13,320 --> 00:00:17,280 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:17,280 --> 00:00:18,450 at ocw.mit.edu. 8 00:00:22,110 --> 00:00:25,092 ERIK DEMAINE: All right, welcome back to 6.851. 9 00:00:25,092 --> 00:00:28,530 We continue our theme of time travel today. 10 00:00:28,530 --> 00:00:30,776 Before I get started, I wanted to briefly talk 11 00:00:30,776 --> 00:00:32,150 about the project, which I forgot 12 00:00:32,150 --> 00:00:33,650 to talk about in lecture one. 13 00:00:33,650 --> 00:00:36,710 Project is sort of the focus of your evaluation in the class, 14 00:00:36,710 --> 00:00:38,380 other than problems sets inscribing, 15 00:00:38,380 --> 00:00:40,590 it's supposed to be the bulk of the work. 16 00:00:40,590 --> 00:00:42,110 Project can be theoretical, trying 17 00:00:42,110 --> 00:00:43,151 to solve an open problem. 18 00:00:43,151 --> 00:00:44,510 You don't have to succeed. 19 00:00:44,510 --> 00:00:46,968 If you want to do that, you should come to the open problem 20 00:00:46,968 --> 00:00:47,480 sessions. 21 00:00:47,480 --> 00:00:51,590 Could be a survey of things, especially not 22 00:00:51,590 --> 00:00:54,500 covered in class, or not covered in class in much detail. 23 00:00:54,500 --> 00:00:55,790 Look at a few papers. 24 00:00:55,790 --> 00:00:58,490 Could be an implementation of one of these data structures. 25 00:00:58,490 --> 00:01:00,890 A lot of the data structures we're talking about here 26 00:01:00,890 --> 00:01:02,056 have never been implemented. 27 00:01:02,056 --> 00:01:04,069 We don't know how well they perform in practice, 28 00:01:04,069 --> 00:01:05,300 and it'd cool to find out. 29 00:01:05,300 --> 00:01:07,216 Many of them have though, so you should do one 30 00:01:07,216 --> 00:01:09,980 that hasn't been done already. 31 00:01:09,980 --> 00:01:11,840 Those are the main project types. 32 00:01:11,840 --> 00:01:14,300 There will in a month or so, there 33 00:01:14,300 --> 00:01:16,280 will be a project proposal deadline where you 34 00:01:16,280 --> 00:01:17,750 have to pick what you're doing. 35 00:01:17,750 --> 00:01:21,500 And then the project itself is due last day of classes. 36 00:01:21,500 --> 00:01:24,200 And in the last few lectures, there 37 00:01:24,200 --> 00:01:25,457 will be project presentations. 38 00:01:25,457 --> 00:01:27,290 So you'll also have to give a talk about it. 39 00:01:27,290 --> 00:01:28,550 You can do group projects. 40 00:01:28,550 --> 00:01:31,850 And for more people we expect more stuff to be done, 41 00:01:31,850 --> 00:01:33,210 that's all. 42 00:01:33,210 --> 00:01:34,880 Otherwise unconstrained. 43 00:01:34,880 --> 00:01:40,340 So in time travel land, I guess the most sort 44 00:01:40,340 --> 00:01:43,450 of physically realistic physics land, 45 00:01:43,450 --> 00:01:45,567 if time travel is branching universes 46 00:01:45,567 --> 00:01:47,150 where if you make a change in the past 47 00:01:47,150 --> 00:01:48,441 you get a totally new universe. 48 00:01:48,441 --> 00:01:50,370 That's full persistence. 49 00:01:50,370 --> 00:01:51,772 That's last class. 50 00:01:51,772 --> 00:01:54,230 Today we're going to do the more science fiction-y approach 51 00:01:54,230 --> 00:01:57,769 to time travel, which is you can-- like in 52 00:01:57,769 --> 00:01:58,560 Back to the Future. 53 00:01:58,560 --> 00:02:00,560 You can go back in time, make a change, 54 00:02:00,560 --> 00:02:02,690 and then return to the present and see all the 55 00:02:02,690 --> 00:02:05,750 intervening-- the result of all the intervening things that 56 00:02:05,750 --> 00:02:08,120 happen meanwhile. 57 00:02:08,120 --> 00:02:10,250 A fun example of this, if you haven't seen it, 58 00:02:10,250 --> 00:02:12,830 is the movie Time Cop, where there's 59 00:02:12,830 --> 00:02:14,810 this guy going back in time, trying 60 00:02:14,810 --> 00:02:17,810 to fight evil time travelers. 61 00:02:17,810 --> 00:02:20,420 And when he returns to the present, 62 00:02:20,420 --> 00:02:22,820 sometimes, like the whole time travel 63 00:02:22,820 --> 00:02:24,140 service is starting to fail. 64 00:02:24,140 --> 00:02:25,370 And there's this worry that he'll never be 65 00:02:25,370 --> 00:02:26,900 able to return to the present. 66 00:02:26,900 --> 00:02:30,240 So anyway, we want to do that with the data structure. 67 00:02:30,240 --> 00:02:33,440 So this is the idea of retroactivity. 68 00:02:33,440 --> 00:02:37,190 In general, we think of a data structure as having a timeline. 69 00:02:46,460 --> 00:02:52,520 We're going to maintain one linear timeline of updates. 70 00:02:52,520 --> 00:02:54,650 So here's time. 71 00:02:57,990 --> 00:03:05,810 And the idea is, well, maybe at time 0 you do an insert of 7. 72 00:03:05,810 --> 00:03:11,600 And then at time 1, you maybe did an insert of 3. 73 00:03:11,600 --> 00:03:14,630 And then at time 2, you did a delete-min. 74 00:03:18,860 --> 00:03:19,960 OK, what's that spell? 75 00:03:19,960 --> 00:03:21,200 Or, at the end you have-- 76 00:03:21,200 --> 00:03:23,810 right now, you'd have just the element 7. 77 00:03:23,810 --> 00:03:26,900 In general, every data structure you can think of is this. 78 00:03:26,900 --> 00:03:30,590 Now normally, we're always appending to the timeline 79 00:03:30,590 --> 00:03:33,200 that's working in the present. 80 00:03:33,200 --> 00:03:35,900 You're doing operations on the present. 81 00:03:35,900 --> 00:03:38,300 But we'd like to allow-- with retroactive data 82 00:03:38,300 --> 00:03:40,760 structures you can go back in time, say 83 00:03:40,760 --> 00:03:43,550 right at the beginning of time, and say actually I 84 00:03:43,550 --> 00:03:48,660 meant to put, at time minus 1, I meant to do something insert 4. 85 00:03:48,660 --> 00:03:52,050 Or actually, insert 2 would be a little more interesting. 86 00:03:52,050 --> 00:03:54,140 Insert 2 is interesting, because that actually 87 00:03:54,140 --> 00:03:56,990 changes what the delete-min operation would have done. 88 00:03:56,990 --> 00:03:58,460 And so I want to go back in time, 89 00:03:58,460 --> 00:04:01,040 do this, and then return to the present, say what's my data 90 00:04:01,040 --> 00:04:02,510 structure look like now. 91 00:04:02,510 --> 00:04:05,990 I want to be able to do the regular queries I can. 92 00:04:05,990 --> 00:04:09,530 So let's say you can do queries at the present. 93 00:04:09,530 --> 00:04:11,420 This is now. 94 00:04:11,420 --> 00:04:15,050 And you can do queries here. 95 00:04:15,050 --> 00:04:21,890 And I want to be able to add and remove operations. 96 00:04:27,170 --> 00:04:30,650 Update operations at any time. 97 00:04:35,430 --> 00:04:38,780 So that's what's called a partially retroactive data 98 00:04:38,780 --> 00:04:41,920 structure. 99 00:04:41,920 --> 00:04:45,620 So like persistence, we have partial and full. 100 00:04:45,620 --> 00:04:51,410 So in general, we're going to have insert at a given 101 00:04:51,410 --> 00:04:53,525 time, a given update. 102 00:04:56,810 --> 00:05:01,970 Delete the operation at a given time. 103 00:05:01,970 --> 00:05:02,800 And query. 104 00:05:10,610 --> 00:05:15,290 And I'm going to use capital letters 105 00:05:15,290 --> 00:05:18,110 to denote retroactive operations and lower case letters 106 00:05:18,110 --> 00:05:19,470 to denote regular operations. 107 00:05:19,470 --> 00:05:20,820 So it's intentional. 108 00:05:20,820 --> 00:05:22,550 This is an uppercase insert. 109 00:05:22,550 --> 00:05:23,850 This is a lowercase insert. 110 00:05:23,850 --> 00:05:29,960 So we're inserting an insert at time, the time before 0. 111 00:05:29,960 --> 00:05:33,380 What exactly does time mean here? 112 00:05:33,380 --> 00:05:36,395 We're not going to work with that too much directly today. 113 00:05:36,395 --> 00:05:38,270 You can think of them as just being integers. 114 00:05:38,270 --> 00:05:41,360 But it gets awkward if you just keep inserting new operations 115 00:05:41,360 --> 00:05:42,920 to do in between 1 and 2. 116 00:05:42,920 --> 00:05:45,900 There aren't very many integers between 1 and 2. 117 00:05:45,900 --> 00:05:48,920 One easy solution to this is use the order maintenance data 118 00:05:48,920 --> 00:05:51,089 structure that we mentioned in the last class, where 119 00:05:51,089 --> 00:05:52,880 you basically are maintaining a linked list 120 00:05:52,880 --> 00:05:56,600 and you're able to insert new times in between any two 121 00:05:56,600 --> 00:05:57,200 given times. 122 00:05:57,200 --> 00:06:00,240 And you can still do order queries in constant time. 123 00:06:00,240 --> 00:06:02,229 But I mean, if you don't mind logs 124 00:06:02,229 --> 00:06:04,520 you could just store the times in a binary search tree. 125 00:06:04,520 --> 00:06:08,280 That's an easy way to do it. 126 00:06:08,280 --> 00:06:12,410 We're not really going to worry about that too much here. 127 00:06:12,410 --> 00:06:14,120 What we're interested here is how do we 128 00:06:14,120 --> 00:06:17,600 maintain the sort of side effects 129 00:06:17,600 --> 00:06:20,210 of doing this operation earlier in time, 130 00:06:20,210 --> 00:06:23,540 computing all of this, or chain reactions that 131 00:06:23,540 --> 00:06:26,900 would have happened meanwhile, sort of butterfly effect. 132 00:06:26,900 --> 00:06:33,980 All right, I want to define partial retroactivity 133 00:06:33,980 --> 00:06:43,200 means queries are always done at the present. 134 00:06:43,200 --> 00:06:46,670 Let's say t equals infinity or now. 135 00:06:46,670 --> 00:06:48,790 This is what you might call the Q model, 136 00:06:48,790 --> 00:06:50,300 if you're a Star Trek fan. 137 00:06:50,300 --> 00:06:52,479 You can exist in all time simultaneously, do updates 138 00:06:52,479 --> 00:06:54,020 whenever you feel like it, do queries 139 00:06:54,020 --> 00:06:57,140 whenever you feel like it. 140 00:06:57,140 --> 00:06:59,780 All right model clear. 141 00:06:59,780 --> 00:07:02,040 Now as you might expect, this is hard. 142 00:07:02,040 --> 00:07:05,580 You can't always do retroactivity super well. 143 00:07:05,580 --> 00:07:08,900 But we'll talk about our situations you can do well 144 00:07:08,900 --> 00:07:10,940 and what you can do in general. 145 00:07:15,315 --> 00:07:20,833 Go to an easy case, which is still fairly interesting. 146 00:07:24,620 --> 00:07:29,720 Suppose you have commutative updates, 147 00:07:29,720 --> 00:07:36,672 meaning x followed by y is the same thing as y followed by x. 148 00:07:36,672 --> 00:07:38,630 This would be great if I could reorder updates, 149 00:07:38,630 --> 00:07:41,600 because then I don't really care about the sequence of updates, 150 00:07:41,600 --> 00:07:45,470 as long as I'm only querying the final results. 151 00:07:45,470 --> 00:07:47,337 If I want to do an update in the past-- 152 00:07:47,337 --> 00:07:49,670 this would not be an example of commutative-- delete-min 153 00:07:49,670 --> 00:07:51,255 and insert are not commutative. 154 00:07:51,255 --> 00:07:54,770 But if I was just doing insert and delete for example, 155 00:07:54,770 --> 00:07:58,787 delete 7, whatever, then inserting 2 here 156 00:07:58,787 --> 00:08:00,620 is the same thing as inserting 2 at the end, 157 00:08:00,620 --> 00:08:03,230 as long as I'm only querying the end. 158 00:08:03,230 --> 00:08:06,640 So this would be an easy case for partial retroactivity. 159 00:08:11,660 --> 00:08:17,450 If my updates are commutative, then inserting an operation 160 00:08:17,450 --> 00:08:25,670 at time t is the same thing as inserting that operation now, 161 00:08:25,670 --> 00:08:26,480 at the end of time. 162 00:08:29,590 --> 00:08:30,830 That's for inserts. 163 00:08:30,830 --> 00:08:33,260 But if I want to also be able to-- 164 00:08:33,260 --> 00:08:36,110 for retroactive inserts, I should say, capital I. 165 00:08:36,110 --> 00:08:39,230 If I want to be able to do retroactive deletes, 166 00:08:39,230 --> 00:08:40,909 I need something else. 167 00:08:40,909 --> 00:08:41,900 I need some way-- 168 00:08:41,900 --> 00:08:45,950 I still want to only work in the present, if I can. 169 00:08:45,950 --> 00:08:48,680 And for that I need inversion. 170 00:08:48,680 --> 00:08:49,820 I have invertible updates. 171 00:08:55,480 --> 00:08:58,760 If there is some way to, given an operation x, 172 00:08:58,760 --> 00:09:02,190 compute a new operation x inverse, that does the reverse, 173 00:09:02,190 --> 00:09:04,610 and that's equivalent to nothing, 174 00:09:04,610 --> 00:09:08,450 then deleting an operation is the same thing as doing 175 00:09:08,450 --> 00:09:09,560 the inverse. 176 00:09:09,560 --> 00:09:11,840 And if you have also commutativity-- 177 00:09:11,840 --> 00:09:17,840 so I'm adding these two constraints-- then delete t 178 00:09:17,840 --> 00:09:27,091 some operation is the same thing as inserting now that operation 179 00:09:27,091 --> 00:09:27,590 inverse. 180 00:09:31,150 --> 00:09:34,920 So that's-- if I have both of these properties, 181 00:09:34,920 --> 00:09:37,320 then partial retroactivity is trivial. 182 00:09:37,320 --> 00:09:40,810 I just do everything in the present. 183 00:09:40,810 --> 00:09:44,080 May not seem very exciting, but it solves a bunch of problems 184 00:09:44,080 --> 00:09:45,370 already for free. 185 00:09:45,370 --> 00:09:48,220 So for example, hashing. 186 00:09:48,220 --> 00:09:51,654 If you want a dynamic hash table or dictionary, 187 00:09:51,654 --> 00:09:53,820 and you want to be able to make retroactive changes, 188 00:09:53,820 --> 00:09:56,236 it really doesn't matter whether you make them in the past 189 00:09:56,236 --> 00:09:57,070 or in the present. 190 00:09:57,070 --> 00:10:00,130 I'm assuming a little bit here that you don't, for example, 191 00:10:00,130 --> 00:10:03,070 clobber a key and write to the same key twice. 192 00:10:03,070 --> 00:10:05,490 Then the order would matter. 193 00:10:05,490 --> 00:10:08,410 But if you store all copies of all keys, then this is true. 194 00:10:10,936 --> 00:10:12,310 Slightly more interesting, if you 195 00:10:12,310 --> 00:10:21,250 have an array with the operation add delta 196 00:10:21,250 --> 00:10:22,480 to a given array element. 197 00:10:22,480 --> 00:10:24,980 So if I had an assignment here, then the order would matter. 198 00:10:24,980 --> 00:10:29,000 But if I have only addition or subtraction, 199 00:10:29,000 --> 00:10:31,180 that's fine, because addition and subtraction 200 00:10:31,180 --> 00:10:32,620 are commutative. 201 00:10:32,620 --> 00:10:34,690 So I can do that. 202 00:10:34,690 --> 00:10:37,792 Not terribly exciting, as you might imagine. 203 00:10:37,792 --> 00:10:40,000 We're going to get to much more interesting examples. 204 00:10:40,000 --> 00:10:44,950 But a natural question here is what about full retroactivity? 205 00:10:44,950 --> 00:10:46,780 So partial's nice. 206 00:10:46,780 --> 00:10:48,991 But if I have such an easy setup, 207 00:10:48,991 --> 00:10:50,365 can I achieve full retroactivity? 208 00:10:50,365 --> 00:10:53,530 It's not so obvious because now working in the present, 209 00:10:53,530 --> 00:10:57,130 it's not correctly reflecting the past. 210 00:10:57,130 --> 00:10:59,170 To do that, we need-- 211 00:10:59,170 --> 00:11:01,210 we cannot do it in general, we don't know how. 212 00:11:01,210 --> 00:11:05,230 But there is a situation where we do know how. 213 00:11:05,230 --> 00:11:07,285 First I'll define a search problem. 214 00:11:11,680 --> 00:11:14,080 The search problem is-- 215 00:11:14,080 --> 00:11:16,880 you've seen many examples of this 216 00:11:16,880 --> 00:11:19,460 in your algorithmic lifetime-- 217 00:11:19,460 --> 00:11:22,960 I maintain a set S of objects-- 218 00:11:22,960 --> 00:11:24,820 we don't know what they are-- 219 00:11:24,820 --> 00:11:30,100 subject to insert, delete, and some kind of search query. 220 00:11:39,280 --> 00:11:42,250 And I want to focus in on the types of queries we allow. 221 00:11:42,250 --> 00:11:45,940 So this in particular, insert and delete 222 00:11:45,940 --> 00:11:47,770 are commutative and invertible. 223 00:11:47,770 --> 00:11:49,220 They are each other's inverses. 224 00:11:49,220 --> 00:11:52,220 So n queries are queries. 225 00:11:52,220 --> 00:11:54,190 This is really just a constraint on updates. 226 00:11:54,190 --> 00:11:57,041 So search problems fall into this easy class. 227 00:11:57,041 --> 00:11:58,540 So in particular, it covers hashing. 228 00:12:01,420 --> 00:12:04,570 Fine, that's a general class of problems. 229 00:12:04,570 --> 00:12:07,990 Here's a slightly less general class of problems, 230 00:12:07,990 --> 00:12:11,180 which are sort of well-studied. 231 00:12:11,180 --> 00:12:13,870 The old geometric data structures literature. 232 00:12:13,870 --> 00:12:15,160 Decomposable search problems. 233 00:12:17,810 --> 00:12:22,060 This is a concept from 1980 revitalized. 234 00:12:22,060 --> 00:12:23,920 I should mention this retroactive paper 235 00:12:23,920 --> 00:12:24,880 is pretty recent. 236 00:12:24,880 --> 00:12:29,412 I think the journal version appeared in 2007. 237 00:12:29,412 --> 00:12:32,269 I have 2003 and 2007 here. 238 00:12:32,269 --> 00:12:34,060 So those are the two versions of the paper. 239 00:12:37,000 --> 00:12:40,640 So what's a decomposable search problem? 240 00:12:40,640 --> 00:12:44,020 Same thing, but the query is of a particular flavor, 241 00:12:44,020 --> 00:12:47,170 has a particular structure. 242 00:12:47,170 --> 00:12:52,560 If I want to do a query on the union of two sets, a and b, 243 00:12:52,560 --> 00:12:55,480 it's the same thing as doing the query on the two sets 244 00:12:55,480 --> 00:12:58,030 individually and then combining them with some function. 245 00:13:06,820 --> 00:13:10,717 This is a constraint on what the query is. 246 00:13:10,717 --> 00:13:11,800 The problem is still this. 247 00:13:11,800 --> 00:13:14,290 I still want to do a query on the entire set. 248 00:13:14,290 --> 00:13:18,220 But I just know this fact, that if I could somehow 249 00:13:18,220 --> 00:13:19,930 solve the query on smaller sets, I 250 00:13:19,930 --> 00:13:23,080 could combine them into the union using this f function. 251 00:13:23,080 --> 00:13:25,510 For some, let's say this can be computed in constant time. 252 00:13:30,329 --> 00:13:31,870 That's a decomposable search problem. 253 00:13:31,870 --> 00:13:35,492 For example, suppose I have a set of points in the plane. 254 00:13:35,492 --> 00:13:37,450 And I want to know, given a query point, what's 255 00:13:37,450 --> 00:13:39,160 the nearest point in my set? 256 00:13:39,160 --> 00:13:43,210 So it would be dynamic nearest neighbor. 257 00:13:43,210 --> 00:13:46,090 If I could compute the nearest neighbor among one subset 258 00:13:46,090 --> 00:13:47,140 of the points, and the nearest neighbor 259 00:13:47,140 --> 00:13:49,660 among a different subset, I can compute the nearest neighbor 260 00:13:49,660 --> 00:13:52,240 among the union just by taking the min of the two. 261 00:13:52,240 --> 00:13:54,490 Doesn't matter whether a and b overlap. 262 00:13:54,490 --> 00:13:56,650 That will still give the right answer. 263 00:13:56,650 --> 00:13:58,720 Sort of a min over all things. 264 00:13:58,720 --> 00:14:02,140 I have some other examples. 265 00:14:02,140 --> 00:14:04,550 Successor on a line. 266 00:14:04,550 --> 00:14:06,220 If I'm given a query point, I want 267 00:14:06,220 --> 00:14:09,190 to know what the next, the nearest item after it is. 268 00:14:09,190 --> 00:14:12,850 That's sort of like one-sided nearest neighbor. 269 00:14:12,850 --> 00:14:16,840 Yeah, point location, we'll get to that in the future. 270 00:14:16,840 --> 00:14:18,590 Don't want to time travel too much. 271 00:14:18,590 --> 00:14:22,760 OK, so some property-- some queries have this property. 272 00:14:22,760 --> 00:14:23,260 Some don't. 273 00:14:23,260 --> 00:14:27,160 If they do-- and we have commutative and invertability-- 274 00:14:27,160 --> 00:14:30,010 I claim full retroactivity becomes easy. 275 00:14:30,010 --> 00:14:31,030 Relatively easy. 276 00:14:31,030 --> 00:14:33,140 Log factor overhead. 277 00:14:33,140 --> 00:14:35,500 So that's what I wanted to show you. 278 00:14:38,170 --> 00:14:43,270 Full retro for decomposable search problems. 279 00:14:48,430 --> 00:14:50,470 Decomposable search problems are automatically 280 00:14:50,470 --> 00:14:52,090 computed of an invertible, so I don't 281 00:14:52,090 --> 00:14:54,410 need to write that constraint. 282 00:14:54,410 --> 00:15:01,110 In log-- I have n here, but I think I mean m-- 283 00:15:01,110 --> 00:15:01,610 overhead. 284 00:15:04,370 --> 00:15:06,790 It's a multiplicative factor. 285 00:15:06,790 --> 00:15:09,089 m here is the number of retroactive operations 286 00:15:09,089 --> 00:15:09,630 you're doing. 287 00:15:09,630 --> 00:15:11,606 So it's the size of the timeline. 288 00:15:15,080 --> 00:15:22,150 OK, we're going to do that via something called a segment 289 00:15:22,150 --> 00:15:29,012 tree, which was introduced in the same paper that 290 00:15:29,012 --> 00:15:31,470 dealt with decomposable search problems by Bentley and Saxe 291 00:15:31,470 --> 00:15:34,450 in 1980. 292 00:15:34,450 --> 00:15:36,850 They weren't thinking about time travel. 293 00:15:36,850 --> 00:15:40,450 Retroactively their result is useful. 294 00:15:40,450 --> 00:15:44,080 So what's a segment tree? 295 00:15:44,080 --> 00:15:45,260 It's a tree. 296 00:15:45,260 --> 00:15:48,490 Let me draw my favorite picture. 297 00:15:48,490 --> 00:15:51,020 Draw this many times in this class, I'm sure. 298 00:15:55,330 --> 00:15:59,440 I would like to build a balanced binary search tree on time. 299 00:15:59,440 --> 00:16:00,475 Leaves will be time. 300 00:16:03,490 --> 00:16:04,015 Here's time. 301 00:16:08,900 --> 00:16:12,969 And the idea is, well, if I have my operations, my updates-- 302 00:16:12,969 --> 00:16:15,010 which are what the things that live on time are-- 303 00:16:15,010 --> 00:16:17,090 are inserts and deletes. 304 00:16:17,090 --> 00:16:19,780 And so if I look at an element, at some point 305 00:16:19,780 --> 00:16:20,890 it might be inserted. 306 00:16:20,890 --> 00:16:22,556 At some point later it might be deleted. 307 00:16:22,556 --> 00:16:25,240 I'm going to assume every element is inserted and deleted 308 00:16:25,240 --> 00:16:27,820 only once. 309 00:16:27,820 --> 00:16:29,660 Otherwise, if it happens multiple times, 310 00:16:29,660 --> 00:16:31,910 think of them as different elements. 311 00:16:31,910 --> 00:16:36,460 Then every element exists for an interval of time. 312 00:16:36,460 --> 00:16:39,940 So for example, maybe I have an element 313 00:16:39,940 --> 00:16:42,880 that exists for this interval of time. 314 00:16:42,880 --> 00:16:46,960 Maybe it gets inserted here and then gets deleted here. 315 00:16:46,960 --> 00:16:50,380 How should I represent that interval in my tree? 316 00:16:50,380 --> 00:16:53,650 Let's call this element a. 317 00:16:53,650 --> 00:16:56,442 Well, if I draw a complete binary tree, 318 00:16:56,442 --> 00:16:58,150 there there's an obvious way to represent 319 00:16:58,150 --> 00:17:04,871 that interval, which is as the union of these four intervals. 320 00:17:04,871 --> 00:17:06,579 If you think of this node as representing 321 00:17:06,579 --> 00:17:08,750 the interval of all of its leaves, 322 00:17:08,750 --> 00:17:11,140 descendant leaves, then I could put a here. 323 00:17:11,140 --> 00:17:16,660 And I could put a here, and here, and here. 324 00:17:16,660 --> 00:17:19,270 I do that for all my elements. 325 00:17:19,270 --> 00:17:21,640 This picture's going to get messy quickly. 326 00:17:21,640 --> 00:17:24,599 Let me just do one more example. 327 00:17:24,599 --> 00:17:31,880 So maybe I have an element from here to here. 328 00:17:31,880 --> 00:17:33,850 Then I'm going to call that element b. 329 00:17:33,850 --> 00:17:36,010 Then I'll put b here. 330 00:17:36,010 --> 00:17:38,950 And I'll put b here. 331 00:17:38,950 --> 00:17:41,650 So always putting it is as high as I can. 332 00:17:41,650 --> 00:17:44,330 I don't want to put b or a in all the leaves it appears in, 333 00:17:44,330 --> 00:17:46,330 because that would be a linear number of leaves. 334 00:17:46,330 --> 00:17:47,950 If I do it like this, there's only 335 00:17:47,950 --> 00:17:50,560 log n subtrees I care about, representing 336 00:17:50,560 --> 00:17:57,000 the interval as a union of log n subtree aligned intervals. 337 00:17:57,000 --> 00:18:01,090 OK, now the real picture is slightly messier than this. 338 00:18:01,090 --> 00:18:03,670 I drew a nice, complete, perfect tree. 339 00:18:03,670 --> 00:18:06,677 In reality, you're inserting new operations in here. 340 00:18:06,677 --> 00:18:08,260 And so you've actually got to maintain 341 00:18:08,260 --> 00:18:09,843 this as a balanced binary search tree. 342 00:18:09,843 --> 00:18:13,560 So use a red-black tree, AVL tree, or pick your favorite. 343 00:18:13,560 --> 00:18:17,420 As long as it stays balanced, you can still do this. 344 00:18:17,420 --> 00:18:19,870 It'll be a little less obvious how to do rotations, 345 00:18:19,870 --> 00:18:22,660 but let's not worry about rotations right now. 346 00:18:22,660 --> 00:18:25,150 Now I want to do a query. 347 00:18:25,150 --> 00:18:26,200 What's a query look like? 348 00:18:26,200 --> 00:18:28,300 Well, I care about all the things done up 349 00:18:28,300 --> 00:18:29,170 to a certain time. 350 00:18:29,170 --> 00:18:31,990 Or really I care about who exists. 351 00:18:31,990 --> 00:18:36,876 Let's say I want to do a query on an array here. 352 00:18:36,876 --> 00:18:39,250 That's maybe not so exciting. 353 00:18:39,250 --> 00:18:43,060 Let's do a query here. 354 00:18:46,090 --> 00:18:49,510 I want to know at this time who exists, 355 00:18:49,510 --> 00:18:51,970 and perform the query on that time. 356 00:18:51,970 --> 00:18:54,340 So really, I'm asking about everything 357 00:18:54,340 --> 00:18:58,930 done in this interval, from the beginning of time 358 00:18:58,930 --> 00:19:01,430 to my query time t. 359 00:19:01,430 --> 00:19:06,550 So here's query of t. 360 00:19:06,550 --> 00:19:08,500 Now we don't know what the query is. 361 00:19:08,500 --> 00:19:10,380 We just know it's on the set. 362 00:19:10,380 --> 00:19:14,720 And we know that is decomposable in this way by a set union. 363 00:19:14,720 --> 00:19:18,070 So the idea is, well I'll do the query on this data structure, 364 00:19:18,070 --> 00:19:20,847 because that represents whatever existed at that time. 365 00:19:20,847 --> 00:19:22,930 And then I'll do the query on this data structure, 366 00:19:22,930 --> 00:19:24,555 because that represents the things that 367 00:19:24,555 --> 00:19:25,930 existed before that. 368 00:19:29,500 --> 00:19:32,240 That doesn't look so great. 369 00:19:32,240 --> 00:19:36,550 OK, so I need to put each element in log n 370 00:19:36,550 --> 00:19:39,310 different nodes in here, such that I 371 00:19:39,310 --> 00:19:42,280 can answer a query by looking at log n different nodes. 372 00:19:42,280 --> 00:19:45,670 And a query is asking about what are all the things that 373 00:19:45,670 --> 00:19:48,480 exist at this time. 374 00:19:48,480 --> 00:19:50,310 So here it would be ab. 375 00:19:50,310 --> 00:19:51,810 Over here it would be nothing. 376 00:19:51,810 --> 00:19:54,884 Over here it would be nothing. 377 00:19:54,884 --> 00:19:56,357 Yeah? 378 00:19:56,357 --> 00:19:58,812 AUDIENCE: If you're querying, the time 379 00:19:58,812 --> 00:20:00,776 correspond to particular [INAUDIBLE].. 380 00:20:00,776 --> 00:20:03,250 Then you can query all the data structures-- 381 00:20:03,250 --> 00:20:05,900 ERIK DEMAINE: OK, maybe I was just doing the queries wrong. 382 00:20:05,900 --> 00:20:08,630 Good, I think that's a good idea. 383 00:20:08,630 --> 00:20:12,080 I guess I'm asking about querying this time. 384 00:20:12,080 --> 00:20:13,850 So which node should I do? 385 00:20:13,850 --> 00:20:15,350 All the ancestors. 386 00:20:19,630 --> 00:20:21,920 I see. 387 00:20:21,920 --> 00:20:24,880 Claim that does it. 388 00:20:24,880 --> 00:20:25,962 Gotta think about it. 389 00:20:25,962 --> 00:20:29,609 AUDIENCE: And then you carry [INAUDIBLE] 390 00:20:29,609 --> 00:20:31,400 ERIK DEMAINE: That definitely gets a and b. 391 00:20:31,400 --> 00:20:32,260 That looks good. 392 00:20:32,260 --> 00:20:34,180 All right, exercise to prove that this works. 393 00:20:38,110 --> 00:20:40,150 I think that is right. 394 00:20:40,150 --> 00:20:42,640 So it's an asymmetry between queries and updates. 395 00:20:42,640 --> 00:20:48,550 For updates, you basically partition the interval. 396 00:20:51,340 --> 00:20:54,784 AUDIENCE: What happens to a very short-lived element 397 00:20:54,784 --> 00:20:57,736 at the very end of the time travel? 398 00:20:57,736 --> 00:21:13,030 [INAUDIBLE] 399 00:21:13,030 --> 00:21:14,530 ERIK DEMAINE: So maybe this works. 400 00:21:14,530 --> 00:21:16,630 I'll think about it offline and I'll 401 00:21:16,630 --> 00:21:18,580 send email if it doesn't work. 402 00:21:18,580 --> 00:21:21,670 But I think this is right. 403 00:21:21,670 --> 00:21:23,320 So for query, you walk up time. 404 00:21:23,320 --> 00:21:25,990 And I'm going to query each of these data structures. 405 00:21:25,990 --> 00:21:28,270 Now this is a logarithmic factor overhead, 406 00:21:28,270 --> 00:21:32,230 both in time and space, because each element might be stored 407 00:21:32,230 --> 00:21:33,480 in log n different structures. 408 00:21:33,480 --> 00:21:35,510 Or what are in these nodes, by the way? 409 00:21:35,510 --> 00:21:38,535 That is your data structure, the non-retroactive version. 410 00:21:38,535 --> 00:21:40,660 So we're storing the non-radioactive data structure 411 00:21:40,660 --> 00:21:43,935 on these guys in order to-- 412 00:21:43,935 --> 00:21:46,990 when I add-- if I modify a's interval, 413 00:21:46,990 --> 00:21:48,490 I delete it from all the places that 414 00:21:48,490 --> 00:21:51,340 used to be in and then reinsert it into all the places 415 00:21:51,340 --> 00:21:51,940 it's now in. 416 00:21:51,940 --> 00:21:54,520 So I'm doing inserts and deletes on log n 417 00:21:54,520 --> 00:21:58,330 of those non-retroactive data structures. 418 00:21:58,330 --> 00:22:01,490 OK, and then I combine with f which is constant time. 419 00:22:01,490 --> 00:22:05,211 So only log factor overhead on the queries. 420 00:22:05,211 --> 00:22:07,390 OK, a little harder than I thought. 421 00:22:10,420 --> 00:22:13,300 So full retro, full retroactivity, 422 00:22:13,300 --> 00:22:16,324 but in this relatively simple special case. 423 00:22:16,324 --> 00:22:17,740 Let's talk about the general case. 424 00:22:37,630 --> 00:22:42,830 There's an obvious way to do full retroactivity, which is-- 425 00:22:42,830 --> 00:22:44,200 let's say partial retroactivity. 426 00:22:44,200 --> 00:22:46,780 I want to know what happened in the present. 427 00:22:46,780 --> 00:22:51,280 The obvious thing to do is write down all the changes you made. 428 00:22:51,280 --> 00:22:53,800 And then if you want to make a retroactive change, 429 00:22:53,800 --> 00:22:57,580 you roll back, do your change, and then replay everything 430 00:22:57,580 --> 00:22:59,200 that happened meanwhile. 431 00:22:59,200 --> 00:23:01,660 So this is the rollback method. 432 00:23:25,470 --> 00:23:31,450 So if I need to go back in time by a factor of r, by r time 433 00:23:31,450 --> 00:23:34,930 units, I pay a factor of r overhead in time. 434 00:23:34,930 --> 00:23:36,010 And space is reasonable. 435 00:23:36,010 --> 00:23:39,670 You just have to remember everything that happened. 436 00:23:39,670 --> 00:23:41,340 This is pretty obvious. 437 00:23:41,340 --> 00:23:42,784 Also old. 438 00:23:42,784 --> 00:23:44,200 Unfortunately, it's about the best 439 00:23:44,200 --> 00:23:47,800 we can do in general, depending on your exact model. 440 00:23:54,492 --> 00:23:55,670 So we add the lower bound. 441 00:24:14,210 --> 00:24:17,900 This is kind of a fun result from a philosophy standpoint, 442 00:24:17,900 --> 00:24:20,142 philosophy of time travel. 443 00:24:20,142 --> 00:24:22,100 It's essentially saying that Back to the Future 444 00:24:22,100 --> 00:24:23,360 is impossible. 445 00:24:23,360 --> 00:24:25,610 I know, it's sad but true. 446 00:24:25,610 --> 00:24:28,850 And there's a good movie about this called Retroactive. 447 00:24:28,850 --> 00:24:31,760 This is a very unknown movie, from '97, 448 00:24:31,760 --> 00:24:37,667 or so, where they play through this sequence of events. 449 00:24:37,667 --> 00:24:39,750 And then there's a time machine which brings them, 450 00:24:39,750 --> 00:24:42,740 I forget, an hour into the past. 451 00:24:42,740 --> 00:24:44,510 And then they have to relive those events. 452 00:24:44,510 --> 00:24:45,882 And they can make changes. 453 00:24:45,882 --> 00:24:47,840 But they have to spend all that time until they 454 00:24:47,840 --> 00:24:48,830 get to the time machine again. 455 00:24:48,830 --> 00:24:51,290 They still didn't get it right, so they go back in time. 456 00:24:51,290 --> 00:24:54,140 And the movie repeats like six times or so, 457 00:24:54,140 --> 00:24:55,660 until they finally get it right. 458 00:24:55,660 --> 00:24:59,030 Or I shouldn't, whatever, forget the ending actually. 459 00:24:59,030 --> 00:25:03,020 So that's realistic in that we know from persistence, 460 00:25:03,020 --> 00:25:05,150 we can remember the past. 461 00:25:05,150 --> 00:25:08,360 And we can jump back into the past and then just relive it. 462 00:25:08,360 --> 00:25:10,610 And maybe make changes along the way. 463 00:25:10,610 --> 00:25:13,520 But the claim is you can't do that any more efficiently 464 00:25:13,520 --> 00:25:16,670 than replaying all of those events, in the worst case, 465 00:25:16,670 --> 00:25:19,760 and I think even in real life. 466 00:25:19,760 --> 00:25:21,300 Should include the worst case. 467 00:25:21,300 --> 00:25:22,460 So let me tell you why. 468 00:25:22,460 --> 00:25:24,920 All we need to live in our universe 469 00:25:24,920 --> 00:25:28,460 for this lower bound to hold is a very simple computer. 470 00:25:41,440 --> 00:25:44,360 It's a computer with two registers, x and y. 471 00:25:44,360 --> 00:25:45,530 They start at zero. 472 00:25:45,530 --> 00:25:46,520 AUDIENCE: Question. 473 00:25:46,520 --> 00:25:46,745 ERIK DEMAINE: Yeah? 474 00:25:46,745 --> 00:25:49,161 AUDIENCE: When you say that the overhead can be necessary, 475 00:25:49,161 --> 00:25:51,520 does that mean that it's sometimes not-- 476 00:25:51,520 --> 00:25:54,194 ERIK DEMAINE: The can be is relative to the data structure. 477 00:25:54,194 --> 00:25:55,610 So there is a data structure where 478 00:25:55,610 --> 00:26:01,430 you're guaranteed to need order r in the worst case. 479 00:26:01,430 --> 00:26:04,804 And probably the average case in all sorts of bad things. 480 00:26:04,804 --> 00:26:06,470 Yeah, so there are some data structures, 481 00:26:06,470 --> 00:26:09,780 like these ones, where you can do better. 482 00:26:09,780 --> 00:26:13,564 And this is for partial retroactivity. 483 00:26:13,564 --> 00:26:15,230 But then there are some data structures, 484 00:26:15,230 --> 00:26:16,670 like the one I'm going to describe to you, 485 00:26:16,670 --> 00:26:17,780 that you cannot do better. 486 00:26:21,707 --> 00:26:22,790 So here are my operations. 487 00:26:22,790 --> 00:26:25,230 I can set x to a value. 488 00:26:25,230 --> 00:26:29,600 I can add a value to y. 489 00:26:29,600 --> 00:26:35,240 I can compute the product of x and y and put it into y. 490 00:26:35,240 --> 00:26:41,350 And then I have a query, which is what is y. 491 00:26:41,350 --> 00:26:45,160 So this is one of the simplest computers ever designed. 492 00:26:45,160 --> 00:26:47,210 A very basic calculator. 493 00:26:47,210 --> 00:26:51,230 But it lets us do-- 494 00:26:51,230 --> 00:26:53,390 Here's what the operations I'm going to do. 495 00:26:53,390 --> 00:26:57,890 First operation-- this is in order of time. 496 00:26:57,890 --> 00:27:01,220 First I will add a into y. 497 00:27:01,220 --> 00:27:04,420 Then I will compute the product. 498 00:27:04,420 --> 00:27:06,220 Then I will compute-- 499 00:27:06,220 --> 00:27:08,675 then I will add a and minus 1 to y. 500 00:27:08,675 --> 00:27:11,900 Then I will compute the product. 501 00:27:11,900 --> 00:27:16,671 And then at the end, I will add a zero to y. 502 00:27:16,671 --> 00:27:17,420 What does that do? 503 00:27:21,090 --> 00:27:22,724 Mathematicians. 504 00:27:22,724 --> 00:27:24,890 AUDIENCE: [INAUDIBLE] 505 00:27:24,890 --> 00:27:27,470 ERIK DEMAINE: Polynomial evaluation. 506 00:27:27,470 --> 00:27:34,650 This is equivalent to computing a n, x to the n-- 507 00:27:34,650 --> 00:27:38,780 well, I guess capital X to the n, a n minus 1, 508 00:27:38,780 --> 00:27:41,655 x to the n minus 1, a0. 509 00:27:44,210 --> 00:27:46,040 OK, I didn't set X at the beginning. 510 00:27:46,040 --> 00:27:49,400 But whatever X was, this sequence of operations 511 00:27:49,400 --> 00:27:50,820 will evaluate this polynomial. 512 00:27:50,820 --> 00:27:53,870 This is called Cramer's rule for evaluating that polynomial. 513 00:27:53,870 --> 00:27:56,660 Just keep multiplying by X in each round, 514 00:27:56,660 --> 00:28:00,130 adding on the next coefficient. 515 00:28:00,130 --> 00:28:01,760 OK, so the result-- 516 00:28:01,760 --> 00:28:03,950 this I'm just going to do at the beginning. 517 00:28:03,950 --> 00:28:06,020 It's like regular operations. 518 00:28:06,020 --> 00:28:13,250 And now I'm going to do things like insert at time 0 519 00:28:13,250 --> 00:28:17,490 that X equals some value. 520 00:28:17,490 --> 00:28:18,560 I'm just going to keep-- 521 00:28:18,560 --> 00:28:21,310 first I'll put it here, then right after, then right after-- 522 00:28:21,310 --> 00:28:22,580 keep doing those insertions. 523 00:28:22,580 --> 00:28:24,740 I completely change what X is. 524 00:28:24,740 --> 00:28:28,310 And so I change where I'm evaluating this polynomial. 525 00:28:28,310 --> 00:28:30,950 And claim is you really can't do that 526 00:28:30,950 --> 00:28:33,740 any faster than reevaluating the polynomial. 527 00:28:33,740 --> 00:28:45,630 In a history independent algebraic decision tree model-- 528 00:28:45,630 --> 00:28:51,830 which I don't want to define precisely, but maybe 529 00:28:51,830 --> 00:28:53,720 computation tree would be better. 530 00:28:53,720 --> 00:28:57,740 Anyway, this is just you draw a tree of all the possible things 531 00:28:57,740 --> 00:28:59,400 you could do. 532 00:28:59,400 --> 00:29:02,750 And the things you can do are additions, multiplications, 533 00:29:02,750 --> 00:29:07,690 subtractions, divisions, all field operations. 534 00:29:07,690 --> 00:29:13,550 So for any field, this would work with reals, would also, 535 00:29:13,550 --> 00:29:17,990 should work for integers module LP. 536 00:29:17,990 --> 00:29:20,690 Any fields. 537 00:29:20,690 --> 00:29:25,910 And the interesting part is independent of preprocessing 538 00:29:25,910 --> 00:29:29,090 of the coefficients, you can stare at those coefficients 539 00:29:29,090 --> 00:29:31,040 however long you like. 540 00:29:31,040 --> 00:29:40,190 In the worst case, you need mega n field operations, 541 00:29:40,190 --> 00:29:43,380 where n is the degree of the polynomial. 542 00:29:43,380 --> 00:29:46,220 So this is a known result from 2001. 543 00:29:46,220 --> 00:29:49,780 And so it tells you that each of these retroactive operations, 544 00:29:49,780 --> 00:29:51,380 it's n time units in the past. 545 00:29:51,380 --> 00:29:53,600 And you need order n time to complete it. 546 00:29:53,600 --> 00:29:55,550 Even though these operations can be 547 00:29:55,550 --> 00:29:58,130 solved in constant time each. 548 00:29:58,130 --> 00:30:01,360 So it's a factor n loss. 549 00:30:01,360 --> 00:30:04,300 Now this is a particular model of computation. 550 00:30:04,300 --> 00:30:06,970 It implies something like an integer or a random access 551 00:30:06,970 --> 00:30:10,120 machine, where you can have arrays, I don't really care. 552 00:30:10,120 --> 00:30:11,920 But as long as the way that you're 553 00:30:11,920 --> 00:30:14,950 manipulating these objects are with field operations, 554 00:30:14,950 --> 00:30:17,470 you're in trouble. 555 00:30:17,470 --> 00:30:19,990 OK, but there are conceivably other things you could do. 556 00:30:23,170 --> 00:30:24,880 If these numbers are integers maybe 557 00:30:24,880 --> 00:30:26,800 I could split their bits into parts 558 00:30:26,800 --> 00:30:28,294 and do crazy things with them. 559 00:30:28,294 --> 00:30:30,460 That's something we'll get to later on in the class. 560 00:30:33,970 --> 00:30:37,654 Even then, you can't do so well. 561 00:30:37,654 --> 00:30:42,122 I guess I'll briefly tell you this because there's 562 00:30:42,122 --> 00:30:43,330 an interesting lower balance. 563 00:30:43,330 --> 00:30:44,860 Oh sorry, interesting open problem. 564 00:30:55,140 --> 00:30:58,720 Cell-probe model, something we'll get into in a deeper way 565 00:30:58,720 --> 00:30:59,900 later on in this class. 566 00:30:59,900 --> 00:31:04,462 But it just says how many objects, 567 00:31:04,462 --> 00:31:06,670 how many words of memory do you need to read in order 568 00:31:06,670 --> 00:31:08,660 to solve your problem? 569 00:31:08,660 --> 00:31:10,930 So that's a lower bound on time. 570 00:31:10,930 --> 00:31:13,420 No matter how you're computing with those numbers, 571 00:31:13,420 --> 00:31:15,790 how many of the objects, how many of the integers 572 00:31:15,790 --> 00:31:17,727 do you need to read? 573 00:31:17,727 --> 00:31:19,810 Not necessarily just the ai's You could split them 574 00:31:19,810 --> 00:31:22,420 into parts, do all kinds of preprocessing, 575 00:31:22,420 --> 00:31:24,121 make a hash table, build whatever 576 00:31:24,121 --> 00:31:25,120 data structure you want. 577 00:31:25,120 --> 00:31:29,050 How many words of that data structure do you need to read? 578 00:31:29,050 --> 00:31:35,990 And the claim is at least square root of r divided by log r. 579 00:31:35,990 --> 00:31:39,490 So roughly square root of r, open problem, 580 00:31:39,490 --> 00:31:44,030 is can you get something like r again in this model? 581 00:31:44,030 --> 00:31:47,169 So this is a very powerful model, not at all realistic. 582 00:31:47,169 --> 00:31:49,210 But if you can prove a lower bound in this model, 583 00:31:49,210 --> 00:31:53,530 then it holds basically all models you could ever think of. 584 00:31:53,530 --> 00:31:55,570 So here's a data structure-- or here's 585 00:31:55,570 --> 00:31:57,790 the proof of this lower bound. 586 00:32:01,420 --> 00:32:03,770 Data structure maintains n words. 587 00:32:06,359 --> 00:32:07,900 I should say typically in this class, 588 00:32:07,900 --> 00:32:14,460 a word is an integer of let's say log n-- 589 00:32:14,460 --> 00:32:15,790 I'll be more precise. 590 00:32:15,790 --> 00:32:17,650 w bits. 591 00:32:17,650 --> 00:32:18,880 w is at least log n. 592 00:32:21,580 --> 00:32:23,170 We'll talk about this a lot more later 593 00:32:23,170 --> 00:32:26,390 in the class when we get to integer data structures. 594 00:32:26,390 --> 00:32:30,850 But if you were wondering what a word means, there it is. 595 00:32:30,850 --> 00:32:34,240 And the operations, the updates you are allowed to do 596 00:32:34,240 --> 00:32:37,520 are arithmetic operations. 597 00:32:37,520 --> 00:32:40,450 So it's generalization of this problem. 598 00:32:40,450 --> 00:32:43,540 You can do addition, multiplication, division, 599 00:32:43,540 --> 00:32:46,341 just basic stuff. 600 00:32:46,341 --> 00:32:48,340 So that's the data structure we're trying to do. 601 00:32:48,340 --> 00:32:52,420 And at the end you can query what is the value of this word. 602 00:32:52,420 --> 00:32:54,910 And now what are we going to do? 603 00:32:54,910 --> 00:32:57,850 Before we did polynomial evaluation in that model. 604 00:32:57,850 --> 00:33:01,660 Now what I'm going to do is compute FFT, fast 605 00:33:01,660 --> 00:33:03,710 Fourier transform. 606 00:33:03,710 --> 00:33:05,180 If you know how to do that great. 607 00:33:05,180 --> 00:33:07,510 If not, it's an n log n algorithm. 608 00:33:07,510 --> 00:33:09,280 So it's an n log in operations you do. 609 00:33:09,280 --> 00:33:12,200 I'm just going to write them down as my sequence of updates. 610 00:33:12,200 --> 00:33:15,340 At the end I have the fast Fourier transform. 611 00:33:15,340 --> 00:33:18,280 And the retroactive thing I'm going to do 612 00:33:18,280 --> 00:33:23,230 is set all of these words, all the xi's, and name them. 613 00:33:23,230 --> 00:33:25,780 Which changes the input to the fast Fourier transform. 614 00:33:25,780 --> 00:33:32,200 And it turns out that dynamic fast Fourier transform, 615 00:33:32,200 --> 00:33:41,440 where changing one of the words, xi, you can show, 616 00:33:41,440 --> 00:33:43,360 or it has been shown-- 617 00:33:43,360 --> 00:33:45,190 we're not going to prove this here-- 618 00:33:45,190 --> 00:33:49,540 requires at least square root of n cell-probes. 619 00:33:52,540 --> 00:33:53,674 So this is about-- 620 00:33:53,674 --> 00:33:55,840 if you change one thing in a fast Fourier transform, 621 00:33:55,840 --> 00:33:58,630 it doesn't change everything, necessarily. 622 00:33:58,630 --> 00:34:01,330 But the claim is that you need to look 623 00:34:01,330 --> 00:34:03,220 at least root n of the things again, 624 00:34:03,220 --> 00:34:06,820 in order to figure out what happened, how the FFT changed. 625 00:34:06,820 --> 00:34:09,610 So I mention this mostly as an interesting question 626 00:34:09,610 --> 00:34:12,310 of whether you can come up with a better lower bound 627 00:34:12,310 --> 00:34:13,750 in this data structure. 628 00:34:13,750 --> 00:34:16,030 Ideally taking some existing lower bound, 629 00:34:16,030 --> 00:34:20,469 plugging it in to this kind of retroactive framework, 630 00:34:20,469 --> 00:34:25,739 and getting what you want. 631 00:34:25,739 --> 00:34:27,310 Enough about the bad news. 632 00:34:27,310 --> 00:34:31,040 I want to go to positive results again. 633 00:34:31,040 --> 00:34:33,520 So we had a very simple thing here. 634 00:34:33,520 --> 00:34:35,020 Let's try something that's somewhere 635 00:34:35,020 --> 00:34:38,980 in between, where there are chain reactions, 636 00:34:38,980 --> 00:34:40,612 but it's not impossible. 637 00:34:40,612 --> 00:34:42,070 So in general, if you're building-- 638 00:34:42,070 --> 00:34:44,445 if you have a data structure that represents an arbitrary 639 00:34:44,445 --> 00:34:46,594 computer, you're basically hosed. 640 00:34:46,594 --> 00:34:48,010 If you have a data structure where 641 00:34:48,010 --> 00:34:50,949 the operations can be arbitrarily reordered, pretty 642 00:34:50,949 --> 00:34:51,699 easy. 643 00:34:51,699 --> 00:34:59,920 So our intermediate setting will be priority queues, the example 644 00:34:59,920 --> 00:35:01,618 I showed at the very beginning. 645 00:35:10,250 --> 00:35:11,920 So on a priority queue, I'm going 646 00:35:11,920 --> 00:35:15,836 to think about two operations, insert and delete-min. 647 00:35:19,240 --> 00:35:22,480 This is interesting because delete-min depends 648 00:35:22,480 --> 00:35:25,750 on what the current state is. 649 00:35:25,750 --> 00:35:27,760 So if I insert something early on, 650 00:35:27,760 --> 00:35:30,730 it can change every delete-min that happens thereafter, 651 00:35:30,730 --> 00:35:34,120 and completely change what happens at the end of the data 652 00:35:34,120 --> 00:35:36,820 structure. 653 00:35:36,820 --> 00:35:38,350 So the claim is we can solve this 654 00:35:38,350 --> 00:35:46,030 with log n time per operation, per partially 655 00:35:46,030 --> 00:35:47,727 retroactive operation. 656 00:35:51,710 --> 00:35:57,125 It's pretty good because in this model, which-- 657 00:35:57,125 --> 00:35:58,910 what model are we in here? 658 00:35:58,910 --> 00:36:02,430 I guess pointer machine would be a reasonable model? 659 00:36:02,430 --> 00:36:05,540 Log n is the best you can hope for a priority queue. 660 00:36:05,540 --> 00:36:08,560 I guess comparison model is more relevant then. 661 00:36:08,560 --> 00:36:10,290 So you can use priority queues to sort. 662 00:36:10,290 --> 00:36:13,340 So log n is the best you can do for regular priority queues. 663 00:36:13,340 --> 00:36:16,460 And so to do it also partially retroactive 664 00:36:16,460 --> 00:36:19,460 is pretty interesting. 665 00:36:19,460 --> 00:36:22,260 How do we do this? 666 00:36:22,260 --> 00:36:25,730 Well, I don't want to draw a picture of what these data 667 00:36:25,730 --> 00:36:26,660 structures look like. 668 00:36:33,230 --> 00:36:38,630 My picture is keyspace is going to be the y-axis, 669 00:36:38,630 --> 00:36:40,730 and time is the x-axis. 670 00:36:43,410 --> 00:36:45,620 So if someone comes along and does an insertion, 671 00:36:45,620 --> 00:36:49,916 they do the insertion at some time with some key value. 672 00:36:49,916 --> 00:36:51,290 And so I'm going to think of that 673 00:36:51,290 --> 00:36:53,373 as a rightward pointing ray, because at that point 674 00:36:53,373 --> 00:36:55,940 that element exists. 675 00:36:55,940 --> 00:36:59,690 And if nothing happens, it will exist for the end of time. 676 00:36:59,690 --> 00:37:02,030 The problem would be if someone comes along and does 677 00:37:02,030 --> 00:37:02,790 a delete-min. 678 00:37:02,790 --> 00:37:08,004 A delete-min is going to be a ray shooting up from infinity, 679 00:37:08,004 --> 00:37:09,920 because you always want to delete the smallest 680 00:37:09,920 --> 00:37:10,880 possible thing. 681 00:37:10,880 --> 00:37:12,920 So whatever this ray hits first, that 682 00:37:12,920 --> 00:37:15,440 is the thing that gets deleted. 683 00:37:15,440 --> 00:37:16,250 So I want to keep-- 684 00:37:16,250 --> 00:37:19,530 I want to draw all those rays for the delete-mins. 685 00:37:19,530 --> 00:37:21,330 So this is a delete-min. 686 00:37:24,460 --> 00:37:27,410 And this is an insert. 687 00:37:27,410 --> 00:37:30,359 So I have rightward rays for insertions. 688 00:37:30,359 --> 00:37:31,400 They start at some point. 689 00:37:31,400 --> 00:37:34,460 And I have upward rays from infinity. 690 00:37:34,460 --> 00:37:37,400 In general, I'm going to get a bunch of L shapes. 691 00:37:52,010 --> 00:37:55,400 And the L's will be non crossing in a legitimate picture 692 00:37:55,400 --> 00:37:58,532 of an execution of the algorithm. 693 00:37:58,532 --> 00:38:01,380 AUDIENCE: The vertical stuff is when you're taking the min out? 694 00:38:01,380 --> 00:38:03,830 ERIK DEMAINE: Yeah the vertical lines are delete-mins. 695 00:38:03,830 --> 00:38:05,494 They're coming from below. 696 00:38:05,494 --> 00:38:07,910 They're taking whatever the smallest thing is that exists. 697 00:38:07,910 --> 00:38:10,760 So think about like this time right here. 698 00:38:10,760 --> 00:38:13,980 Right now these four elements are in the data structure. 699 00:38:13,980 --> 00:38:16,400 You do a delete-min, you delete the smallest one. 700 00:38:16,400 --> 00:38:18,150 So this guy dies. 701 00:38:18,150 --> 00:38:19,760 But the three others continue. 702 00:38:19,760 --> 00:38:22,800 Maybe there'll be some elements that just exist. 703 00:38:22,800 --> 00:38:24,110 They don't get deleted. 704 00:38:24,110 --> 00:38:25,490 So it's not entirely L's. 705 00:38:25,490 --> 00:38:28,370 That's sort of a half of an L. So you 706 00:38:28,370 --> 00:38:30,950 might have some L's like that that just go off to infinity. 707 00:38:33,770 --> 00:38:35,850 But everyone that's in an L, this 708 00:38:35,850 --> 00:38:37,100 is the insertion that made it. 709 00:38:37,100 --> 00:38:39,014 These are the delete-mins that deleted it. 710 00:38:39,014 --> 00:38:41,430 We're not going to do arbitrary deletes, just delete-mins. 711 00:38:41,430 --> 00:38:44,110 It's hard enough. 712 00:38:44,110 --> 00:38:46,380 OK, problem clear? 713 00:38:46,380 --> 00:38:48,800 So I want to maintain this. 714 00:38:48,800 --> 00:38:55,850 Let me show you what goes wrong, the hard part about this data 715 00:38:55,850 --> 00:38:57,680 structure. 716 00:38:57,680 --> 00:39:02,660 Let's say I do an insert here. 717 00:39:02,660 --> 00:39:04,100 New insertion. 718 00:39:04,100 --> 00:39:06,650 Well, that means that this delete-min would have returned 719 00:39:06,650 --> 00:39:08,420 this guy instead of this one. 720 00:39:08,420 --> 00:39:11,141 So this one would actually continue to exist. 721 00:39:11,141 --> 00:39:12,890 So then this delete-min would have deleted 722 00:39:12,890 --> 00:39:15,110 this guy instead of that one. 723 00:39:15,110 --> 00:39:17,070 So this guy continues to exist. 724 00:39:17,070 --> 00:39:20,710 So this continues to the right. 725 00:39:20,710 --> 00:39:22,920 This starts exist until this delete-min, 726 00:39:22,920 --> 00:39:24,870 and now this one exists. 727 00:39:24,870 --> 00:39:28,370 OK, and then this one exists for the rest of time. 728 00:39:28,370 --> 00:39:31,640 In general, you do a single retroactive insert, 729 00:39:31,640 --> 00:39:33,280 everything could change. 730 00:39:33,280 --> 00:39:35,510 Or a linear number of guys could change. 731 00:39:39,302 --> 00:39:41,760 So if you want to maintain this picture, you're in trouble. 732 00:39:41,760 --> 00:39:44,187 You get an omega r lower bound. 733 00:39:44,187 --> 00:39:46,020 So we're not going to maintain this picture. 734 00:39:46,020 --> 00:39:47,686 But we're going to keep it in our minds, 735 00:39:47,686 --> 00:39:51,030 vaguely, that we wanted to know something like this picture. 736 00:39:51,030 --> 00:39:53,940 What we really need to know is that this element now 737 00:39:53,940 --> 00:39:55,845 exists in the data structure. 738 00:39:55,845 --> 00:39:57,720 If I'm just doing partial retroactivity, what 739 00:39:57,720 --> 00:40:01,120 I care about is who exists at the end of time. 740 00:40:01,120 --> 00:40:04,500 So I'm doing an insert at a given time t, 741 00:40:04,500 --> 00:40:08,290 with a given key x. 742 00:40:08,290 --> 00:40:11,840 And if life was good, you know, if I was commutative, 743 00:40:11,840 --> 00:40:13,590 then that would be equivalent to inserting 744 00:40:13,590 --> 00:40:15,130 that key x at the end of time. 745 00:40:15,130 --> 00:40:16,080 But it's not. 746 00:40:16,080 --> 00:40:17,550 Instead I have to figure out what 747 00:40:17,550 --> 00:40:19,740 key gets inserted at the end when 748 00:40:19,740 --> 00:40:21,450 I insert this key at this time. 749 00:40:21,450 --> 00:40:24,200 And similarly for adding a delete-min. 750 00:40:24,200 --> 00:40:26,520 I won't try to draw that, but exactly the same kind 751 00:40:26,520 --> 00:40:29,680 of chain reactions can happen. 752 00:40:29,680 --> 00:40:32,610 OK, so we're going to do this in log n time. 753 00:40:53,850 --> 00:40:54,960 How do we do it? 754 00:41:01,130 --> 00:41:04,910 So I'm going to focus on the insertion case, inserting-- 755 00:41:04,910 --> 00:41:06,440 the double insertion case-- 756 00:41:06,440 --> 00:41:09,166 inserting an insert operation. 757 00:41:09,166 --> 00:41:11,540 I guess I'm going to switch notation and call the keys k, 758 00:41:11,540 --> 00:41:12,590 instead of x. 759 00:41:12,590 --> 00:41:13,340 It doesn't matter. 760 00:41:22,440 --> 00:41:24,200 OK, what I'd like to know is that when 761 00:41:24,200 --> 00:41:28,712 I do this insertion, what gets inserted into the final Q? 762 00:41:28,712 --> 00:41:30,170 I'm going to call that Q now, being 763 00:41:30,170 --> 00:41:33,820 the the present, the future, whatever you want to call it. 764 00:41:36,620 --> 00:41:46,245 I claim this is what gets inserted. 765 00:41:53,530 --> 00:41:55,905 If you look at all the keys that get deleted from now on, 766 00:41:55,905 --> 00:41:57,613 and you look at the key you're inserting, 767 00:41:57,613 --> 00:41:59,100 you take the max of all those, that 768 00:41:59,100 --> 00:42:00,960 will be the one that survives. 769 00:42:00,960 --> 00:42:02,640 That's pretty obvious. 770 00:42:02,640 --> 00:42:06,150 The annoying thing is this is really hard to think about. 771 00:42:06,150 --> 00:42:08,730 Because who gets deleted is something that 772 00:42:08,730 --> 00:42:10,560 is a chain reaction effect. 773 00:42:10,560 --> 00:42:13,134 What we'd really like to have is the word inserted there, 774 00:42:13,134 --> 00:42:15,050 because we know what things get inserted when. 775 00:42:15,050 --> 00:42:16,091 Those are the operations. 776 00:42:16,091 --> 00:42:18,700 We just maintain the list of operations, we'd know that. 777 00:42:18,700 --> 00:42:21,510 Deleted is a lot harder to think about. 778 00:42:21,510 --> 00:42:25,290 So we need a Lemma that tells us-- 779 00:42:25,290 --> 00:42:29,160 there's a nice equation that simplifies this formula for us, 780 00:42:29,160 --> 00:42:31,030 or this computation. 781 00:42:31,030 --> 00:42:34,270 For that we need the notion of a bridge. 782 00:42:34,270 --> 00:42:37,770 A very simple idea. 783 00:42:37,770 --> 00:42:45,150 A bridge at time t is a time when 784 00:42:45,150 --> 00:42:47,160 everything that's currently in the queue 785 00:42:47,160 --> 00:42:48,390 will finally be in the queue. 786 00:42:51,880 --> 00:42:56,040 So this is a bridge. 787 00:42:56,040 --> 00:42:57,630 This is a bridge. 788 00:42:57,630 --> 00:43:01,050 Because these elements exist for the rest of time. 789 00:43:01,050 --> 00:43:03,610 This is a bridge. 790 00:43:03,610 --> 00:43:05,370 OK, these are basically-- 791 00:43:05,370 --> 00:43:07,230 interesting stuff happens between bridges. 792 00:43:07,230 --> 00:43:11,430 Bridges are the points of rest when things are kind of boring. 793 00:43:11,430 --> 00:43:15,691 We'll need this for the next statement. 794 00:43:18,867 --> 00:43:20,700 And the other claim is it's easy to maintain 795 00:43:20,700 --> 00:43:21,616 where the bridges are. 796 00:43:21,616 --> 00:43:23,477 That's not a big surprise. 797 00:43:23,477 --> 00:43:25,560 Because there's no chain reactions at the bridges. 798 00:43:40,330 --> 00:43:42,400 So if I have a time t that I care about-- 799 00:43:42,400 --> 00:43:45,370 I want to compute this formula for time t-- 800 00:43:45,370 --> 00:43:47,770 what I do is find the preceding bridge. 801 00:43:47,770 --> 00:43:49,610 Call it t prime. 802 00:43:49,610 --> 00:43:53,002 This is like-- an arbitrary time t like here, 803 00:43:53,002 --> 00:43:54,460 we're in the middle of some action. 804 00:43:54,460 --> 00:43:55,918 I want to know what that action is. 805 00:43:55,918 --> 00:43:58,850 So I want to go to the preceding blue line. 806 00:43:58,850 --> 00:44:00,680 So that's t prime. 807 00:44:00,680 --> 00:44:04,750 If my query is here, t prime will be there. 808 00:44:07,550 --> 00:44:14,800 Then, what I want to know is this max of k prime where k 809 00:44:14,800 --> 00:44:23,157 prime is deleted after time t. 810 00:44:27,450 --> 00:44:30,564 I should say greater equal to t, instead of after, 811 00:44:30,564 --> 00:44:31,480 a little more precise. 812 00:44:35,230 --> 00:44:42,660 Claim this equals the max over all k prime 813 00:44:42,660 --> 00:44:45,760 not in the final queue, because those guys obviously 814 00:44:45,760 --> 00:44:46,270 still exist. 815 00:44:50,050 --> 00:44:59,930 Where k prime is inserted at time greater than 816 00:44:59,930 --> 00:45:02,940 or equal to t prime. 817 00:45:02,940 --> 00:45:05,930 So basically I can turn the word deleted into the word inserted, 818 00:45:05,930 --> 00:45:07,930 if I change t to t prime. 819 00:45:07,930 --> 00:45:10,770 And I also have to exclude the guys at the top. 820 00:45:10,770 --> 00:45:14,247 So we're looking at a particular time like here. 821 00:45:14,247 --> 00:45:15,830 I want to know who are the things that 822 00:45:15,830 --> 00:45:16,880 are deleted after that. 823 00:45:16,880 --> 00:45:17,844 Well, this is deleted. 824 00:45:17,844 --> 00:45:18,510 This is deleted. 825 00:45:18,510 --> 00:45:21,170 All these guys are deleted after. 826 00:45:21,170 --> 00:45:23,807 I'm going to rewind to t prime and say, well, you 827 00:45:23,807 --> 00:45:25,640 know there are these guys that they survive. 828 00:45:25,640 --> 00:45:27,015 They obviously don't get deleted. 829 00:45:27,015 --> 00:45:31,100 But if you ignore the guys that end up in the final queue, 830 00:45:31,100 --> 00:45:33,795 the guys that get deleted after time t 831 00:45:33,795 --> 00:45:36,170 are the same as the ones that get inserted after t prime. 832 00:45:38,792 --> 00:45:39,500 That's the claim. 833 00:45:39,500 --> 00:45:42,230 Or actually, that set of elements is not the same, 834 00:45:42,230 --> 00:45:43,910 but the max will be the same. 835 00:45:43,910 --> 00:45:45,384 That's all I care about. 836 00:45:45,384 --> 00:45:46,550 I only want to know the max. 837 00:45:46,550 --> 00:45:48,320 The max among all the ones deleted here 838 00:45:48,320 --> 00:45:51,529 is this upper uppermost segment. 839 00:45:51,529 --> 00:45:53,570 And that's the same as the max among all the guys 840 00:45:53,570 --> 00:45:54,960 that are inserted after here. 841 00:45:54,960 --> 00:45:57,560 So it's really just a claim about this one being 842 00:45:57,560 --> 00:46:01,649 inserted after this bridge. 843 00:46:01,649 --> 00:46:02,690 I won't prove this Lemma. 844 00:46:02,690 --> 00:46:05,320 It's just, you think about it for long enough, it 845 00:46:05,320 --> 00:46:06,770 becomes obvious. 846 00:46:06,770 --> 00:46:08,792 Leave it at that. 847 00:46:08,792 --> 00:46:10,250 Now we can do some data structures, 848 00:46:10,250 --> 00:46:12,440 because now we have something that we can reasonably 849 00:46:12,440 --> 00:46:13,148 hope to maintain. 850 00:46:21,220 --> 00:46:23,470 So maintaining bridges, one thing-- 851 00:46:27,170 --> 00:46:29,910 Yeah, actually kind of an important thing. 852 00:46:32,469 --> 00:46:34,010 So here's where we're going to store. 853 00:46:34,010 --> 00:46:38,040 We're going to store the current Q as a balanced binary search 854 00:46:38,040 --> 00:46:39,620 tree. 855 00:46:39,620 --> 00:46:43,056 OK, that's not very exciting. 856 00:46:43,056 --> 00:46:45,450 Though the hard part is to figure out how 857 00:46:45,450 --> 00:46:47,630 Q now is changing at each step. 858 00:46:47,630 --> 00:46:49,890 But this will allow us to do arbitrary queries 859 00:46:49,890 --> 00:46:53,280 on the final result 860 00:46:53,280 --> 00:47:02,760 We want to store a balanced binary search tree whose leaves 861 00:47:02,760 --> 00:47:04,230 represent insertions. 862 00:47:08,400 --> 00:47:10,455 So lowercase insertions. 863 00:47:10,455 --> 00:47:13,075 So that's all of the rightward arrows. 864 00:47:15,960 --> 00:47:18,600 And they're are going to be sorted by time. 865 00:47:23,270 --> 00:47:26,540 Not by a key value. 866 00:47:26,540 --> 00:47:29,160 OK, and I'm going to augment that balanced binary search 867 00:47:29,160 --> 00:47:39,540 tree with a fun value for every node 868 00:47:39,540 --> 00:47:41,190 in the balanced binary search tree. 869 00:47:41,190 --> 00:47:44,820 I want to know max of all the keys 870 00:47:44,820 --> 00:47:48,090 not currently in the queue, or not 871 00:47:48,090 --> 00:47:50,582 presently in the queue at the end of time. 872 00:47:50,582 --> 00:47:53,580 That changes is very slowly, so this is easy to maintain. 873 00:47:57,510 --> 00:47:59,340 Among all the keys that are inserted 874 00:47:59,340 --> 00:48:04,210 in the subtree rooted at x. 875 00:48:04,210 --> 00:48:08,220 OK, that's basically this value, which I want to maintain, 876 00:48:08,220 --> 00:48:10,350 but split up over a subtree. 877 00:48:10,350 --> 00:48:12,240 And so that lets me easily compute this value 878 00:48:12,240 --> 00:48:18,470 by taking the max of log n of these values at any time. 879 00:48:18,470 --> 00:48:23,310 OK, then we store another balanced binary search tree 880 00:48:23,310 --> 00:48:25,410 where the leaves are all the updates. 881 00:48:31,610 --> 00:48:33,210 Again they will be ordered by time. 882 00:48:41,040 --> 00:48:42,792 And they will be augmented. 883 00:48:50,360 --> 00:48:53,250 In each node, I'm going to store a number which 884 00:48:53,250 --> 00:48:55,440 is 0 plus 1 or minus 1. 885 00:48:55,440 --> 00:48:58,950 It's going to be 0 for an insert. 886 00:49:01,587 --> 00:49:03,420 This is at the leaf level because the leaves 887 00:49:03,420 --> 00:49:06,480 correspond to updates. 888 00:49:06,480 --> 00:49:11,940 If that key ends up in the final queue. 889 00:49:11,940 --> 00:49:14,020 So those we just ignore. 890 00:49:14,020 --> 00:49:18,630 It's going to be plus 1 for any other kind of insert. 891 00:49:21,300 --> 00:49:27,430 Inserting a key where k is not in Q now. 892 00:49:27,430 --> 00:49:30,375 And it's going to be minus 1 for a delete-min. 893 00:49:35,810 --> 00:49:37,470 I'm going to store this. 894 00:49:37,470 --> 00:49:41,435 And we're going to have subtree sums. 895 00:49:45,330 --> 00:49:49,200 So this is fun with augmentation. 896 00:49:49,200 --> 00:49:51,680 Why do I do all that? 897 00:49:51,680 --> 00:49:57,920 Because if I store all these numbers, 898 00:49:57,920 --> 00:50:00,660 it becomes really easy to detect bridges. 899 00:50:04,442 --> 00:50:05,434 I claim. 900 00:50:14,527 --> 00:50:15,360 AUDIENCE: Professor? 901 00:50:15,360 --> 00:50:16,151 ERIK DEMAINE: Yeah? 902 00:50:16,151 --> 00:50:19,099 AUDIENCE: So, what we're looking for is basically 903 00:50:19,099 --> 00:50:23,874 we know how the cascade went in any given-- 904 00:50:23,874 --> 00:50:26,290 ERIK DEMAINE: We want to compute how one of these cascades 905 00:50:26,290 --> 00:50:26,790 will end. 906 00:50:26,790 --> 00:50:29,325 AUDIENCE: And so we just always maintain that information? 907 00:50:29,325 --> 00:50:31,700 ERIK DEMAINE: We're always going to maintain what's here. 908 00:50:31,700 --> 00:50:33,820 We can't afford to maintain this whole picture 909 00:50:33,820 --> 00:50:35,800 because it changes too much. 910 00:50:35,800 --> 00:50:36,960 But we want to-- 911 00:50:36,960 --> 00:50:37,720 we're given this. 912 00:50:37,720 --> 00:50:39,520 We want to know the result of the cascade, 913 00:50:39,520 --> 00:50:42,000 without having to do all that stuff in the middle. 914 00:50:42,000 --> 00:50:43,530 Yeah, that's our goal. 915 00:50:43,530 --> 00:50:46,040 And I claim-- this is a lot of text. 916 00:50:46,040 --> 00:50:47,800 But I claim that this information 917 00:50:47,800 --> 00:50:50,200 is enough to do that in log n time. 918 00:50:50,200 --> 00:50:52,620 So let me try to convince you. 919 00:50:52,620 --> 00:50:55,470 AUDIENCE: So are you storing several binary searches? 920 00:50:55,470 --> 00:50:57,960 ERIK DEMAINE: I'm storing three. 921 00:50:57,960 --> 00:51:00,370 I'm storing one that represents the final result. 922 00:51:00,370 --> 00:51:02,920 I'm storing one that's just looking at the insertions. 923 00:51:02,920 --> 00:51:05,360 I'm storing one that looks at all the updates. 924 00:51:05,360 --> 00:51:07,780 I maintain all three, and you can cross-link them 925 00:51:07,780 --> 00:51:10,700 all you want. 926 00:51:10,700 --> 00:51:18,910 OK, I claim a bridge is now a prefix 927 00:51:18,910 --> 00:51:30,250 of updates summing to zero, according to this measure. 928 00:51:30,250 --> 00:51:33,730 Because inserts and deletes, when they all cancel out-- 929 00:51:33,730 --> 00:51:37,990 and if we ignore the things that finally end up there, 930 00:51:37,990 --> 00:51:41,200 the periods of rest, when no one is active 931 00:51:41,200 --> 00:51:42,820 that will eventually get deleted, 932 00:51:42,820 --> 00:51:46,420 that's exactly when everyone to the left has been deleted 933 00:51:46,420 --> 00:51:48,080 or will survive to the end. 934 00:51:48,080 --> 00:51:52,540 So these guys counts as zeros, so we ignore those. 935 00:51:52,540 --> 00:51:54,040 Each of these corresponds to plus 1. 936 00:51:54,040 --> 00:51:55,980 Each of these corresponds to a minus 1. 937 00:51:55,980 --> 00:51:58,460 So these have all canceled out by now. 938 00:51:58,460 --> 00:52:00,670 And when this prefix sum, which is everything 939 00:52:00,670 --> 00:52:05,170 up to a given point, is zero, then that is a bridge. 940 00:52:05,170 --> 00:52:09,700 What this lets you do is if you have some-- 941 00:52:09,700 --> 00:52:12,070 you have this binary search tree. 942 00:52:12,070 --> 00:52:15,160 You have some query time t, which corresponds to a leaf. 943 00:52:15,160 --> 00:52:18,490 And now I want to know what is the preceding bridge? 944 00:52:18,490 --> 00:52:22,150 I want to know t prime, the bridge proceeding time t. 945 00:52:22,150 --> 00:52:24,820 Then basically I walk up this tree 946 00:52:24,820 --> 00:52:26,700 and find the preceding moments-- 947 00:52:26,700 --> 00:52:30,520 I actually have to first walk down to compute all the sums. 948 00:52:30,520 --> 00:52:33,520 So hanging off on the left of this path 949 00:52:33,520 --> 00:52:36,895 are all these times in the past. 950 00:52:36,895 --> 00:52:42,165 And I say well, if the sum of all of those subtree sums, sum 951 00:52:42,165 --> 00:52:44,290 of all the values in those leaves, if that's 0 then 952 00:52:44,290 --> 00:52:46,990 we're already at a bridge. 953 00:52:46,990 --> 00:52:49,990 If not, I basically compute the preceding point where 954 00:52:49,990 --> 00:52:52,820 this sum up to that point is 0. 955 00:52:52,820 --> 00:52:54,940 And that should be relatively obvious how to do. 956 00:52:54,940 --> 00:52:58,300 It's a regular kind of walking up the tree. 957 00:52:58,300 --> 00:53:02,580 So log n time I can find the preceding bridge. 958 00:53:07,450 --> 00:53:09,790 Because I have all these subtrees sums 959 00:53:09,790 --> 00:53:19,300 I can do that by a tree walk. 960 00:53:19,300 --> 00:53:24,370 OK, then it just says here, "And then you 961 00:53:24,370 --> 00:53:26,440 can compute the change to Qnow." 962 00:53:26,440 --> 00:53:29,410 How do we compute the change to Qnow? 963 00:53:29,410 --> 00:53:32,950 We have to compute this max of all the keys 964 00:53:32,950 --> 00:53:36,230 that are inserted after time t prime. 965 00:53:36,230 --> 00:53:38,515 So this was the tree of all updates. 966 00:53:41,290 --> 00:53:46,780 And we have another tree, which is just the tree of insertions. 967 00:53:46,780 --> 00:53:48,880 And so if we cross-link time-- so 968 00:53:48,880 --> 00:53:53,200 we find t prime, where the prefix sum is zero. 969 00:53:53,200 --> 00:53:56,260 We map over to t prime here. 970 00:53:56,260 --> 00:53:58,210 And again we get a root to leaf path. 971 00:53:58,210 --> 00:54:00,490 And now we look at all of the elements hanging off 972 00:54:00,490 --> 00:54:03,082 the right side. 973 00:54:03,082 --> 00:54:04,540 Those are all the elements that are 974 00:54:04,540 --> 00:54:06,430 inserted after time t prime. 975 00:54:06,430 --> 00:54:07,870 And I just take the max of those. 976 00:54:07,870 --> 00:54:09,328 So I guess I didn't write it, but I 977 00:54:09,328 --> 00:54:10,760 need to store our subtree-- 978 00:54:10,760 --> 00:54:12,190 oh no, I store this. 979 00:54:12,190 --> 00:54:13,615 Right, this is what I want. 980 00:54:13,615 --> 00:54:14,990 For every subtree, I want to know 981 00:54:14,990 --> 00:54:16,573 the max of the things in that subtree, 982 00:54:16,573 --> 00:54:20,680 but ignoring the guys that are in Qnow. 983 00:54:20,680 --> 00:54:25,550 I take all those maxes on all those subtrees. 984 00:54:25,550 --> 00:54:36,190 And I can find what element gets inserted into Qnow in log n 985 00:54:36,190 --> 00:54:37,159 time. 986 00:54:37,159 --> 00:54:39,450 Then, of course, I have to update all this information. 987 00:54:39,450 --> 00:54:41,140 And I don't want to spend any more 988 00:54:41,140 --> 00:54:44,170 time on this, no pun intended. 989 00:54:44,170 --> 00:54:46,750 You have to-- then Qnow changes. 990 00:54:46,750 --> 00:54:50,560 And so you've got to update all these values and these values. 991 00:54:50,560 --> 00:54:53,830 But the claim is that you can do all that in log n time. 992 00:54:53,830 --> 00:54:56,730 It's not hard. 993 00:54:56,730 --> 00:54:58,380 OK, that's priority queues. 994 00:54:58,380 --> 00:55:00,450 So I know that was a little bit tedious. 995 00:55:00,450 --> 00:55:02,626 But this is sort of-- 996 00:55:02,626 --> 00:55:04,750 it's not quite the coolest thing we know how to do, 997 00:55:04,750 --> 00:55:06,800 but it was the first cool thing we knew how 998 00:55:06,800 --> 00:55:08,190 to do in the retroactive world. 999 00:55:08,190 --> 00:55:11,400 It's this nice borderline where it looks scary. 1000 00:55:11,400 --> 00:55:13,680 There are linear-sized chain reactions. 1001 00:55:13,680 --> 00:55:18,840 Yet we can still deal with them in log n time. 1002 00:55:18,840 --> 00:55:24,000 So not quite the worst case, but also not easy. 1003 00:55:24,000 --> 00:55:26,490 So in general, if you want a retroactive data structure 1004 00:55:26,490 --> 00:55:29,880 for your favorite data structure, 1005 00:55:29,880 --> 00:55:32,130 you're going to have to think along these lines, 1006 00:55:32,130 --> 00:55:36,600 see whether you can maintain something reasonable. 1007 00:55:36,600 --> 00:55:42,030 Let me tell you briefly about other problems, other data 1008 00:55:42,030 --> 00:55:44,350 structures that we've looked at, and other people have 1009 00:55:44,350 --> 00:55:44,850 looked at. 1010 00:55:50,140 --> 00:55:55,830 So a simple one is a queue, first in, first out first in, 1011 00:55:55,830 --> 00:55:56,690 last out. 1012 00:55:56,690 --> 00:55:58,020 One of those. 1013 00:55:58,020 --> 00:56:00,390 I've got stacks too, probably. 1014 00:56:00,390 --> 00:56:03,780 You can do constant time partial retroactivity. 1015 00:56:03,780 --> 00:56:09,584 Log n time full retroactivity for a deque. 1016 00:56:09,584 --> 00:56:12,000 I mentioned this last time where you can insert and delete 1017 00:56:12,000 --> 00:56:13,680 from either end. 1018 00:56:13,680 --> 00:56:21,220 We can do log n full retroactivity for union-find. 1019 00:56:24,360 --> 00:56:25,440 You have a bunch of sets. 1020 00:56:25,440 --> 00:56:26,790 You want to be able to take their union. 1021 00:56:26,790 --> 00:56:29,380 And given an element you want to know which set it's in. 1022 00:56:29,380 --> 00:56:32,980 It's sometimes taught in 6046. 1023 00:56:32,980 --> 00:56:38,316 The best thing we know is log m fully retroactive. 1024 00:56:41,970 --> 00:56:43,851 Priority queue we already talked about. 1025 00:56:43,851 --> 00:56:44,350 But-- 1026 00:56:44,350 --> 00:56:46,150 AUDIENCE: [INAUDIBLE] 1027 00:56:46,150 --> 00:56:49,565 ERIK DEMAINE: Is there a question? 1028 00:56:49,565 --> 00:56:51,854 Priority queue, we already did partial retroactivity. 1029 00:56:51,854 --> 00:56:53,520 But what if you want full retroactivity? 1030 00:56:53,520 --> 00:56:55,550 This is pretty much an open problem. 1031 00:56:55,550 --> 00:56:59,700 Best thing we know is square root of m to m's log n. 1032 00:56:59,700 --> 00:57:01,639 This is via-- we have a general result that 1033 00:57:01,639 --> 00:57:03,930 says if you have anything that's partially retroactive, 1034 00:57:03,930 --> 00:57:05,580 you can make it fully retroactive 1035 00:57:05,580 --> 00:57:09,180 at a huge cost of square root of m factor. 1036 00:57:09,180 --> 00:57:12,560 So you could take what we have, make it fully retroactive. 1037 00:57:12,560 --> 00:57:13,780 Full. 1038 00:57:13,780 --> 00:57:16,365 AUDIENCE: Is there any difference when you're 1039 00:57:16,365 --> 00:57:19,387 talking about n [INAUDIBLE] 1040 00:57:19,387 --> 00:57:20,970 ERIK DEMAINE: n, I think it's supposed 1041 00:57:20,970 --> 00:57:25,339 to be the current size of the data structure. 1042 00:57:25,339 --> 00:57:26,880 I'm not actually sure what that means 1043 00:57:26,880 --> 00:57:28,110 with a retroactive operation. 1044 00:57:28,110 --> 00:57:30,510 I'll just make them all m's. 1045 00:57:30,510 --> 00:57:33,250 I think that's safer. 1046 00:57:33,250 --> 00:57:34,730 Other question or same one? 1047 00:57:34,730 --> 00:57:38,780 OK good, thank you. 1048 00:57:38,780 --> 00:57:41,237 OK, let me tell you about the most important problem 1049 00:57:41,237 --> 00:57:41,820 in this field. 1050 00:57:44,730 --> 00:57:46,440 This is actually what motivated us 1051 00:57:46,440 --> 00:57:50,310 to define retroactivity, which is a particular problem, 1052 00:57:50,310 --> 00:57:51,750 retroactive successor. 1053 00:57:51,750 --> 00:57:56,040 So successor problem is I want to be able to insert and delete 1054 00:57:56,040 --> 00:57:58,500 keys in one dimension. 1055 00:57:58,500 --> 00:58:00,690 And given a query key, I want to know 1056 00:58:00,690 --> 00:58:02,640 what is the next key greater or equal to it. 1057 00:58:02,640 --> 00:58:04,181 This is something you can do in log n 1058 00:58:04,181 --> 00:58:06,580 time with a balanced binary search tree. 1059 00:58:06,580 --> 00:58:08,080 There's lots of other ways to do it, 1060 00:58:08,080 --> 00:58:10,050 which we will get to later in this class. 1061 00:58:10,050 --> 00:58:13,170 But what if I want to do it fully retroactive? 1062 00:58:13,170 --> 00:58:15,420 Partially retroactive is really easy, 1063 00:58:15,420 --> 00:58:20,100 because this is a search problem. 1064 00:58:20,100 --> 00:58:25,550 So I can definitely do log m partial retroactivity. 1065 00:58:28,540 --> 00:58:30,235 In fact, it is a-- 1066 00:58:30,235 --> 00:58:33,900 I just use a regular binary search tree, or whatever. 1067 00:58:33,900 --> 00:58:37,350 In fact, it is a decomposable search problem. 1068 00:58:37,350 --> 00:58:39,920 So I get full retroactivity, no problem. 1069 00:58:39,920 --> 00:58:41,760 But I pay a log factor, so I get log 1070 00:58:41,760 --> 00:58:45,870 squared m, full retroactivity. 1071 00:58:45,870 --> 00:58:50,640 And so that's where we left it, back in 2003. 1072 00:58:50,640 --> 00:58:52,290 But there's a new result, which is 1073 00:58:52,290 --> 00:58:56,170 that you can actually get log m without the square full 1074 00:58:56,170 --> 00:58:58,680 retroactivity. 1075 00:58:58,680 --> 00:59:03,370 This is a complicated result. It's by Goran and Kaplan, 2009. 1076 00:59:03,370 --> 00:59:06,060 It uses fun techniques like fractional cascading, which 1077 00:59:06,060 --> 00:59:11,400 is next lecture, and van Emde Boas, which is lecture 11, 1078 00:59:11,400 --> 00:59:14,560 and various other tools. 1079 00:59:14,560 --> 00:59:17,790 So it's a little too advanced to cover now. 1080 00:59:17,790 --> 00:59:19,500 But it's cool. 1081 00:59:19,500 --> 00:59:21,960 And it has lots of applications in geometry, which we will 1082 00:59:21,960 --> 00:59:23,580 be talking about next class. 1083 00:59:23,580 --> 00:59:27,790 So hold your breath for that, I guess. 1084 00:59:27,790 --> 00:59:28,980 Yeah. 1085 00:59:28,980 --> 00:59:32,640 I want to go to one last topic, which 1086 00:59:32,640 --> 01:00:28,330 is a different kind of retro activity 1087 01:00:28,330 --> 01:00:32,300 Nonoblivious retroactivity is introduced by Acar, Blelloch, 1088 01:00:32,300 --> 01:00:36,320 Tangwongsan in 2007. 1089 01:00:36,320 --> 01:00:38,900 And it's basically answering the question 1090 01:00:38,900 --> 01:00:40,610 "What about my queries?" 1091 01:00:40,610 --> 01:00:44,720 So we have this timeline of updates. 1092 01:00:44,720 --> 01:00:47,810 And we've done various operations 1093 01:00:47,810 --> 01:00:51,924 on our data structure, which are the updates. 1094 01:00:51,924 --> 01:00:53,840 And we've considered how those can be changed. 1095 01:00:53,840 --> 01:00:56,150 And then with queries, either we're querying at the end 1096 01:00:56,150 --> 01:00:57,282 or querying in the middle. 1097 01:00:57,282 --> 01:00:59,240 But we're always getting sort of instantaneous, 1098 01:00:59,240 --> 01:01:03,200 as the timeline exists right now, here's what 1099 01:01:03,200 --> 01:01:05,120 the result of your query is. 1100 01:01:05,120 --> 01:01:07,190 But what if I want to do-- 1101 01:01:07,190 --> 01:01:10,370 I mean, if I really-- normally when I use a data structure, 1102 01:01:10,370 --> 01:01:11,630 I do some updates. 1103 01:01:11,630 --> 01:01:13,550 I do some queries. 1104 01:01:13,550 --> 01:01:17,030 I do a combination of these things. 1105 01:01:17,030 --> 01:01:21,320 And to make life worse, when I do a query, 1106 01:01:21,320 --> 01:01:23,090 the result of that query probably 1107 01:01:23,090 --> 01:01:25,530 influences what updates I do in the future. 1108 01:01:25,530 --> 01:01:28,060 So real use, I'll just call that the algorithmic 1109 01:01:28,060 --> 01:01:29,543 use of a data structure. 1110 01:01:36,800 --> 01:01:41,622 Results of queries influence updates, 1111 01:01:41,622 --> 01:01:42,830 what updates are going to do. 1112 01:01:47,370 --> 01:01:52,557 OK, and now this gets a little dicey, because what 1113 01:01:52,557 --> 01:01:53,390 does influence mean? 1114 01:01:53,390 --> 01:01:56,360 We don't know, because that's the user somehow 1115 01:01:56,360 --> 01:01:59,310 depends on these results. 1116 01:01:59,310 --> 01:02:02,780 So nonoblivious retroactivity is trying to deal with this issue. 1117 01:02:02,780 --> 01:02:05,190 Can we get something reasonable? 1118 01:02:05,190 --> 01:02:07,370 So what we'd like to do is say, oh I now 1119 01:02:07,370 --> 01:02:10,220 add an update over here, retroactively. 1120 01:02:10,220 --> 01:02:13,300 So their updates are the same, in some sense. 1121 01:02:13,300 --> 01:02:18,260 You can retroactively insert and delete updates and queries now. 1122 01:02:18,260 --> 01:02:21,980 I'd like to know well, did the result of this query change? 1123 01:02:21,980 --> 01:02:23,150 Maybe you can show-- 1124 01:02:23,150 --> 01:02:24,920 at the data structure level we can tell 1125 01:02:24,920 --> 01:02:27,260 did that query result change. 1126 01:02:27,260 --> 01:02:30,980 Maybe this one changed, but this one did not. 1127 01:02:30,980 --> 01:02:32,510 What we'd like to report to the user 1128 01:02:32,510 --> 01:02:36,080 is what is the first query that changed, 1129 01:02:36,080 --> 01:02:38,790 because that's like the first mistake that you made. 1130 01:02:38,790 --> 01:02:40,640 Like oh you know, retroactively oops 1131 01:02:40,640 --> 01:02:43,610 I should have deposited $100 back here. 1132 01:02:43,610 --> 01:02:45,620 And then these queries which we're 1133 01:02:45,620 --> 01:02:48,200 checking whether the balance was positive or negative, 1134 01:02:48,200 --> 01:02:52,130 some of their results might change, some of them might not. 1135 01:02:52,130 --> 01:02:54,500 If they change, then the algorithm has to-- 1136 01:02:54,500 --> 01:02:56,600 I mean, it doesn't have to rerun these operations, 1137 01:02:56,600 --> 01:02:59,000 because that's what retroactivity buys for you. 1138 01:02:59,000 --> 01:03:02,120 But it has to say, oh well, now this query has changed. 1139 01:03:02,120 --> 01:03:05,580 And then you have to rerun the algorithm from that point. 1140 01:03:05,580 --> 01:03:07,940 But not necessarily entirely. 1141 01:03:07,940 --> 01:03:10,714 I mean, you look at that and say, oh, 1142 01:03:10,714 --> 01:03:12,380 did that query actually change anything? 1143 01:03:12,380 --> 01:03:14,120 This is now the algorithm. 1144 01:03:14,120 --> 01:03:17,840 Oh yeah, instead of this update here, I would have made 1145 01:03:17,840 --> 01:03:20,060 a different update u prime. 1146 01:03:20,060 --> 01:03:21,810 Well, that's good, we know how to do that. 1147 01:03:21,810 --> 01:03:23,610 That's a retroactive update. 1148 01:03:23,610 --> 01:03:25,970 So I can delete this operation retroactively 1149 01:03:25,970 --> 01:03:27,775 and insert this one. 1150 01:03:27,775 --> 01:03:29,900 So in general, what we assume the algorithm does is 1151 01:03:29,900 --> 01:03:32,810 it looks at the first error, which is 1152 01:03:32,810 --> 01:03:35,130 reported by our data structure. 1153 01:03:35,130 --> 01:03:38,690 And then it then may make various changes 1154 01:03:38,690 --> 01:03:41,266 from that point onward, but always monotonically 1155 01:03:41,266 --> 01:03:42,640 left to right, as if it was rerun 1156 01:03:42,640 --> 01:03:47,670 in the algorithm, but just changing what needed to change, 1157 01:03:47,670 --> 01:03:49,860 until all the errors are resolved. 1158 01:03:49,860 --> 01:03:52,920 All the queries have been corrected to the right answers. 1159 01:03:52,920 --> 01:03:54,450 Then it can do whatever it wants. 1160 01:03:54,450 --> 01:03:57,860 Then it can do retroactive operation anytime in the past. 1161 01:03:57,860 --> 01:04:01,050 OK, so this is an assumption. 1162 01:04:01,050 --> 01:04:15,150 Assume once there's an error, that the algorithm makes 1163 01:04:15,150 --> 01:04:26,220 changes, retroactive updates, from left to right. 1164 01:04:31,260 --> 01:04:41,460 And also going to assume that it does it at times less than 1165 01:04:41,460 --> 01:04:42,555 or equal to all errors. 1166 01:04:46,980 --> 01:04:50,920 So in general, you have a timeline. 1167 01:04:50,920 --> 01:04:56,280 And then there are some errors where bad queries were done. 1168 01:04:56,280 --> 01:04:57,919 Naturally, you would go right here 1169 01:04:57,919 --> 01:04:59,460 and fix the first error, because that 1170 01:04:59,460 --> 01:05:01,540 may influence other errors. 1171 01:05:01,540 --> 01:05:03,260 And maybe you have-- 1172 01:05:03,260 --> 01:05:04,770 so then you make that change. 1173 01:05:04,770 --> 01:05:06,600 Maybe then that causes some other changes 1174 01:05:06,600 --> 01:05:09,370 right after or somewhere in between. 1175 01:05:09,370 --> 01:05:12,270 But then I don't want to make a change here, 1176 01:05:12,270 --> 01:05:14,610 because that would be depending on this result, which 1177 01:05:14,610 --> 01:05:15,290 was incorrect. 1178 01:05:15,290 --> 01:05:17,280 So first you have to fix this. 1179 01:05:17,280 --> 01:05:20,550 So you keep going to the right and you visit all the stars. 1180 01:05:20,550 --> 01:05:23,962 That's this assumption. 1181 01:05:26,800 --> 01:05:28,920 This is a very different kind of retroactivity. 1182 01:05:28,920 --> 01:05:34,140 I would say it's more about maintaining this exact picture 1183 01:05:34,140 --> 01:05:38,160 of what's happening, but being able to teleport over 1184 01:05:38,160 --> 01:05:40,320 the uninteresting stuff. 1185 01:05:40,320 --> 01:05:43,950 So in this picture, if we're doing priority queues 1186 01:05:43,950 --> 01:05:45,990 like this, when I make this change, 1187 01:05:45,990 --> 01:05:47,130 well, that query changes. 1188 01:05:47,130 --> 01:05:48,310 That query changes. 1189 01:05:48,310 --> 01:05:52,740 The delete-mins, the mins that they're deleting change. 1190 01:05:52,740 --> 01:05:54,150 So here they were just updates. 1191 01:05:54,150 --> 01:05:57,057 But if there's also a query here, which is what is the min, 1192 01:05:57,057 --> 01:05:58,890 then all of these query values would change. 1193 01:06:02,420 --> 01:06:05,390 So you're forced now to pay for that. 1194 01:06:05,390 --> 01:06:07,520 So in some sense, it gets easier. 1195 01:06:07,520 --> 01:06:08,290 Let's say. 1196 01:06:08,290 --> 01:06:11,210 For a lot of problems this kind of retroactivity is easier. 1197 01:06:11,210 --> 01:06:13,220 But for many problems, it's also more useful. 1198 01:06:13,220 --> 01:06:16,640 So their example is what if you want to do a dynamic Dijkstra? 1199 01:06:16,640 --> 01:06:18,130 So you have Dijkstra's algorithm, 1200 01:06:18,130 --> 01:06:21,120 and then you say, oh, actually this edge weight was wrong. 1201 01:06:21,120 --> 01:06:22,941 So you run Dijkstra's algorithm once. 1202 01:06:22,941 --> 01:06:24,940 You've got a priority queue in there telling you 1203 01:06:24,940 --> 01:06:26,740 which vertex is next. 1204 01:06:29,251 --> 01:06:31,000 And now you say, OK, I changed this weight 1205 01:06:31,000 --> 01:06:32,680 at the beginning of time. 1206 01:06:32,680 --> 01:06:34,690 I don't want to have to rerun Dijkstra entirely 1207 01:06:34,690 --> 01:06:36,040 if nothing changes. 1208 01:06:36,040 --> 01:06:38,240 Maybe that weight was completely irrelevant. 1209 01:06:38,240 --> 01:06:40,422 If you just do a retroactive update and see 1210 01:06:40,422 --> 01:06:42,880 did any of the query results change, if they didn't change, 1211 01:06:42,880 --> 01:06:44,421 then great you have the right answer. 1212 01:06:44,421 --> 01:06:46,090 If they did change, the results change. 1213 01:06:46,090 --> 01:06:48,970 And so you have to know for every wrong query 1214 01:06:48,970 --> 01:06:51,520 that oh, I really had to change the shortest pathway. 1215 01:06:51,520 --> 01:06:53,440 It's not this, it's now this. 1216 01:06:53,440 --> 01:06:55,099 But hopefully, you will only have 1217 01:06:55,099 --> 01:06:56,890 to change a very small amount if your graph 1218 01:06:56,890 --> 01:06:58,900 didn't change in a big way. 1219 01:06:58,900 --> 01:07:02,680 So it's hard to proof results about that, but at least 1220 01:07:02,680 --> 01:07:05,050 this would let you dynamize almost any algorithm that's 1221 01:07:05,050 --> 01:07:06,220 using the data structure. 1222 01:07:06,220 --> 01:07:10,960 So it's easier, but useful for that kind of transformation. 1223 01:07:10,960 --> 01:07:16,420 OK, let me give you an example, which is priority queues. 1224 01:07:16,420 --> 01:07:20,679 There's a bunch of results in their paper, but for symmetry. 1225 01:07:20,679 --> 01:07:21,970 Tell you about priority queues. 1226 01:07:21,970 --> 01:07:24,440 This will look completely different, so don't worry. 1227 01:07:27,150 --> 01:07:30,470 Operations-- well, the visual picture is the same, 1228 01:07:30,470 --> 01:07:33,950 but the data structuring is all completely different. 1229 01:07:33,950 --> 01:07:36,990 They can do all these things in log m 1230 01:07:36,990 --> 01:07:41,050 per retroactive operation. 1231 01:07:41,050 --> 01:07:43,780 Now there's no notion of full and partial. 1232 01:07:43,780 --> 01:07:46,420 It's just nonoblivious retroactivity. 1233 01:07:46,420 --> 01:07:48,820 I didn't write it here, but the data structure always 1234 01:07:48,820 --> 01:07:52,255 maintains what is the earliest error currently. 1235 01:07:55,510 --> 01:08:02,570 Maintain the earliest in time error. 1236 01:08:02,570 --> 01:08:05,410 That error is a query that used to return one result, 1237 01:08:05,410 --> 01:08:09,180 now returns a new result. 1238 01:08:09,180 --> 01:08:16,910 OK we have a similar picture. 1239 01:08:16,910 --> 01:08:19,185 So I cheated-- I've changed things a little bit. 1240 01:08:19,185 --> 01:08:19,810 I didn't cheat. 1241 01:08:19,810 --> 01:08:22,670 It's just a slight discrepancy. 1242 01:08:22,670 --> 01:08:25,675 For retroactive, regular retroactive, insert and 1243 01:08:25,675 --> 01:08:27,050 delete-min were more interesting, 1244 01:08:27,050 --> 01:08:28,675 because then they were chain reactions. 1245 01:08:28,675 --> 01:08:31,279 In this world you don't have to combine delete and min. 1246 01:08:31,279 --> 01:08:33,890 You could consider delete separate from min. 1247 01:08:33,890 --> 01:08:36,632 Because now, updates are allowed to depend on queries. 1248 01:08:36,632 --> 01:08:38,090 So maybe you compute a min and then 1249 01:08:38,090 --> 01:08:40,010 you decide to delete that thing. 1250 01:08:40,010 --> 01:08:42,439 If the min changes, well then, the thing that got deleted 1251 01:08:42,439 --> 01:08:43,229 might also change. 1252 01:08:43,229 --> 01:08:45,560 That's the algorithm's choice. 1253 01:08:45,560 --> 01:08:47,580 What to do. 1254 01:08:47,580 --> 01:08:50,689 So in this new world of insert, delete, and min, slightly more 1255 01:08:50,689 --> 01:08:56,050 general, if you look at an item, it gets inserted at some time. 1256 01:08:56,050 --> 01:08:57,492 It might get deleted at some time. 1257 01:08:57,492 --> 01:08:59,075 Sometimes it might go off to infinity, 1258 01:08:59,075 --> 01:09:01,729 if it never gets deleted. 1259 01:09:01,729 --> 01:09:07,290 OK, this is our new picture of the priority queue over time. 1260 01:09:07,290 --> 01:09:10,100 So again, this is the time axis. 1261 01:09:10,100 --> 01:09:12,760 And this is the key value. 1262 01:09:12,760 --> 01:09:14,310 So have some inserts, deletes. 1263 01:09:14,310 --> 01:09:16,460 They're all corresponding points in here. 1264 01:09:16,460 --> 01:09:19,700 And then you have min queries, which maybe I will draw in red. 1265 01:09:22,649 --> 01:09:26,550 So min query would be something like this. 1266 01:09:26,550 --> 01:09:28,920 Give me what is the lowest segment at this time. 1267 01:09:34,100 --> 01:09:35,580 So that's my sequence of operations 1268 01:09:35,580 --> 01:09:37,706 is the projection onto time, so there's this thing. 1269 01:09:37,706 --> 01:09:38,705 Then there's this query. 1270 01:09:38,705 --> 01:09:39,965 Then there's this insertion. 1271 01:09:39,965 --> 01:09:41,090 Then there's this deletion. 1272 01:09:41,090 --> 01:09:42,215 Then there's this deletion. 1273 01:09:42,215 --> 01:09:43,215 Then there's this query. 1274 01:09:43,215 --> 01:09:44,839 Min query, then there's this insertion. 1275 01:09:44,839 --> 01:09:45,910 Then there's this query. 1276 01:09:45,910 --> 01:09:47,034 Then there's this deletion. 1277 01:09:47,034 --> 01:09:49,479 You get the idea. 1278 01:09:49,479 --> 01:09:51,240 But this is a way to two-dimensionalize 1279 01:09:51,240 --> 01:09:53,259 that picture. 1280 01:09:53,259 --> 01:09:55,050 AUDIENCE: Can you delete without the query? 1281 01:09:55,050 --> 01:09:56,158 ERIK DEMAINE: Sorry? 1282 01:09:56,158 --> 01:09:58,600 AUDIENCE: Can you delete without the query? 1283 01:09:58,600 --> 01:10:02,484 ERIK DEMAINE: You can delete without a query in this model. 1284 01:10:02,484 --> 01:10:03,900 Make our life a little bit harder. 1285 01:10:03,900 --> 01:10:07,690 Now what we need to support are capital insert, and capital 1286 01:10:07,690 --> 01:10:10,780 delete, retroactive insert and delete, of all three 1287 01:10:10,780 --> 01:10:11,646 of these operations. 1288 01:10:11,646 --> 01:10:12,770 Before it was just updates. 1289 01:10:12,770 --> 01:10:15,660 Now we can insert and delete queries. 1290 01:10:15,660 --> 01:10:17,180 A little harder to think about. 1291 01:10:17,180 --> 01:10:20,270 But it can be done. 1292 01:10:20,270 --> 01:10:22,264 So for example, let's just-- 1293 01:10:22,264 --> 01:10:23,680 I'm not going to do all the cases, 1294 01:10:23,680 --> 01:10:25,670 because there's a lot of them. 1295 01:10:25,670 --> 01:10:30,580 Let's say I delete this deletion. 1296 01:10:30,580 --> 01:10:33,310 OK, that means that this will just go to the right. 1297 01:10:37,550 --> 01:10:41,620 OK, that's bad, because it changes all of these queries. 1298 01:10:41,620 --> 01:10:43,750 All of these queries are now incorrect. 1299 01:10:43,750 --> 01:10:46,090 We're just going to keep the picture like this 1300 01:10:46,090 --> 01:10:47,787 and remember that there are errors. 1301 01:10:47,787 --> 01:10:49,870 And we'll be able to maintain at every moment what 1302 01:10:49,870 --> 01:10:51,760 is the next error. 1303 01:10:51,760 --> 01:10:55,000 The errors are these crossings. 1304 01:10:55,000 --> 01:10:55,750 Crossings are bad. 1305 01:10:55,750 --> 01:10:58,270 That means you have the wrong picture. 1306 01:10:58,270 --> 01:10:59,820 But we'll wait for the algorithm-- 1307 01:10:59,820 --> 01:11:01,690 we'll tell the algorithm this is the next crossing. 1308 01:11:01,690 --> 01:11:04,148 And it's going to have to fix it by say deleting that query 1309 01:11:04,148 --> 01:11:05,230 and then reinserting it. 1310 01:11:05,230 --> 01:11:06,760 Then it will get the correct result. 1311 01:11:06,760 --> 01:11:08,620 But it might do other updates meanwhile. 1312 01:11:08,620 --> 01:11:12,100 So let's not try to fix them all now because they may change. 1313 01:11:12,100 --> 01:11:14,950 Maybe they'll decide to re-insert a deletion here 1314 01:11:14,950 --> 01:11:17,565 to do that, and then erase all of those crossings, 1315 01:11:17,565 --> 01:11:20,210 if we're lucky. 1316 01:11:20,210 --> 01:11:22,270 You might also insert an insertion. 1317 01:11:22,270 --> 01:11:24,640 That's basically the same as deleting a deletion. 1318 01:11:24,640 --> 01:11:26,220 You get a whole bunch of crossings. 1319 01:11:30,050 --> 01:11:32,680 Inserting an insertion and deleting a deletion 1320 01:11:32,680 --> 01:11:34,330 are about the same. 1321 01:11:34,330 --> 01:11:36,880 So the other case is inserting a deletion 1322 01:11:36,880 --> 01:11:40,670 or deleting an insertion. 1323 01:11:40,670 --> 01:11:44,200 So inserting a deletion. 1324 01:11:44,200 --> 01:11:48,170 Let's say that I insert a deletion here. 1325 01:11:48,170 --> 01:11:51,220 So now suddenly this thing ceases to exist. 1326 01:11:51,220 --> 01:11:52,540 All of this is gone. 1327 01:11:52,540 --> 01:11:54,280 We get not a crossing error, but we 1328 01:11:54,280 --> 01:11:56,494 get what I'll call a floating air, which 1329 01:11:56,494 --> 01:11:58,660 is that these guys are currently returning something 1330 01:11:58,660 --> 01:12:02,290 that there's no segment there. 1331 01:12:02,290 --> 01:12:06,100 OK, so we can get crossing errors and floating errors. 1332 01:12:14,660 --> 01:12:16,660 I want to give you enough of this data structure 1333 01:12:16,660 --> 01:12:20,050 to show that actually you use these data structures to solve 1334 01:12:20,050 --> 01:12:22,247 it. 1335 01:12:22,247 --> 01:12:24,455 So in that sense, it's actually not that much easier. 1336 01:12:24,455 --> 01:12:25,996 I said it was easier, but we're going 1337 01:12:25,996 --> 01:12:31,840 to need a retroactive successor in order to solve this problem. 1338 01:12:31,840 --> 01:12:34,295 OK, some variants. 1339 01:12:46,836 --> 01:12:48,210 Man, who used this colored chalk? 1340 01:12:48,210 --> 01:12:49,170 It's so hard to erase. 1341 01:13:03,740 --> 01:13:13,796 Let's say I want to maintain the lowest leftmost crossing. 1342 01:13:20,341 --> 01:13:22,590 So in this picture, where I have a bunch of crossings, 1343 01:13:22,590 --> 01:13:25,690 this is the one I want to maintain, the bottom left one. 1344 01:13:25,690 --> 01:13:27,450 Now there's a bit of a subtlety here, 1345 01:13:27,450 --> 01:13:29,984 which is do you do you minimize y-coordinate 1346 01:13:29,984 --> 01:13:30,900 and then x-coordinate? 1347 01:13:30,900 --> 01:13:31,680 Or vice versa? 1348 01:13:31,680 --> 01:13:33,263 It turns out these are the same thing. 1349 01:13:36,760 --> 01:13:40,590 I don't want to prove that here, but because of this assumption 1350 01:13:40,590 --> 01:13:44,110 that we're always proceeding monotonically left to right, 1351 01:13:44,110 --> 01:13:47,520 we have a nice invariant that if you look at all the crossings, 1352 01:13:47,520 --> 01:13:51,144 they involve segments that start to the left of all errors. 1353 01:13:51,144 --> 01:13:52,560 Because all the changes we've made 1354 01:13:52,560 --> 01:13:56,010 are to the left of all errors by this property. 1355 01:13:56,010 --> 01:13:57,660 And so it's really just a whole bunch 1356 01:13:57,660 --> 01:14:00,840 of rays coming in from negative infinity on the left, 1357 01:14:00,840 --> 01:14:03,630 and a whole bunch of rays coming from minus infinity 1358 01:14:03,630 --> 01:14:05,010 on the bottom. 1359 01:14:05,010 --> 01:14:07,200 Sometimes the rays stop. 1360 01:14:07,200 --> 01:14:08,860 But if you look at where they cross, 1361 01:14:08,860 --> 01:14:11,730 there's a uniquely defined bottom left corner. 1362 01:14:11,730 --> 01:14:16,482 OK, so that's this picture. 1363 01:14:16,482 --> 01:14:21,090 Those rays might go different amounts from either side, 1364 01:14:21,090 --> 01:14:24,910 but there is a single lower left corner. 1365 01:14:24,910 --> 01:14:26,890 So we're going to maintain that. 1366 01:14:26,890 --> 01:14:38,220 And we're also going to maintain the leftmost floating point, 1367 01:14:38,220 --> 01:14:44,330 floating error, on each row separately. 1368 01:14:44,330 --> 01:14:46,949 So in each horizontal line, like here, 1369 01:14:46,949 --> 01:14:48,990 we'll maintain that there's a floating error here 1370 01:14:48,990 --> 01:14:49,980 for this row. 1371 01:14:49,980 --> 01:14:53,200 But we won't figure out that one till later. 1372 01:14:53,200 --> 01:14:55,880 That just saves the work we have to do. 1373 01:14:55,880 --> 01:15:06,360 OK, now let me show you an operation let's do insert min. 1374 01:15:06,360 --> 01:15:07,236 So I want to-- 1375 01:15:07,236 --> 01:15:08,610 I'm going to use x for time here, 1376 01:15:08,610 --> 01:15:10,680 because it's a little bit more intuitive. 1377 01:15:10,680 --> 01:15:12,660 X-coordinate is time. 1378 01:15:12,660 --> 01:15:14,430 Suppose I want to insert a query. 1379 01:15:14,430 --> 01:15:17,580 This is actually an easy case because there's 1380 01:15:17,580 --> 01:15:19,056 no chain reactions here. 1381 01:15:19,056 --> 01:15:21,680 It's going to be correct because I'm doing the query right now. 1382 01:15:21,680 --> 01:15:24,300 This is basically a fully retroactive query. 1383 01:15:24,300 --> 01:15:26,950 I'm adding a new time, a new query, 1384 01:15:26,950 --> 01:15:29,220 and I want to know what is the first ray that I hit. 1385 01:15:32,830 --> 01:15:33,760 How do I solve that? 1386 01:15:37,800 --> 01:15:43,380 So what's going on here is I'm basically manipulating 1387 01:15:43,380 --> 01:15:46,020 these line segments. 1388 01:15:46,020 --> 01:15:50,070 I mean, the red lines don't really affect this query. 1389 01:15:50,070 --> 01:15:51,337 They just might be incorrect. 1390 01:15:51,337 --> 01:15:52,920 But I don't care if they're incorrect. 1391 01:15:52,920 --> 01:15:54,270 I just want to know for this query, what 1392 01:15:54,270 --> 01:15:55,186 is the lowest segment? 1393 01:15:55,186 --> 01:15:56,560 So really, I have segments. 1394 01:15:56,560 --> 01:15:57,510 They're changing. 1395 01:15:57,510 --> 01:16:00,280 Inserting and deleting endpoints of the segments. 1396 01:16:00,280 --> 01:16:03,330 And I want to know from below, what is 1397 01:16:03,330 --> 01:16:05,190 the first segment that I hit? 1398 01:16:05,190 --> 01:16:08,810 This is called upward ray-shooting. 1399 01:16:08,810 --> 01:16:10,620 Or vertical ray-shooting, I guess, 1400 01:16:10,620 --> 01:16:12,960 would be the normal phrasing, but I want 1401 01:16:12,960 --> 01:16:14,390 to be a little more specific. 1402 01:16:14,390 --> 01:16:17,610 Not downward upward. 1403 01:16:17,610 --> 01:16:18,975 Among dynamic segments. 1404 01:16:22,589 --> 01:16:23,880 This is a well-studied problem. 1405 01:16:27,960 --> 01:16:30,110 And conveniently, it can be solved in log n time 1406 01:16:30,110 --> 01:16:30,750 preparation. 1407 01:16:30,750 --> 01:16:35,850 So you can modify segments and do upward ray-shooting queries 1408 01:16:35,850 --> 01:16:37,620 in log n type preparation. 1409 01:16:37,620 --> 01:16:40,590 But you already knew that. 1410 01:16:40,590 --> 01:16:42,630 Good, you're nodding your head. 1411 01:16:42,630 --> 01:16:45,030 Because that is retroactive successor, 1412 01:16:45,030 --> 01:16:46,520 if you think about it. 1413 01:16:46,520 --> 01:16:49,950 A retroactive insertion operation in the past 1414 01:16:49,950 --> 01:16:52,620 is like its fully retroactive successor. 1415 01:16:52,620 --> 01:16:55,260 That's this result. 1416 01:16:55,260 --> 01:16:57,720 Inserting an insertion, that's like creating 1417 01:16:57,720 --> 01:16:59,670 a new left endpoint point of a segment. 1418 01:16:59,670 --> 01:17:02,230 Inserting a deletion is like creating a new right endpoint. 1419 01:17:02,230 --> 01:17:05,400 Deleting a deletion or deleting an insertion, 1420 01:17:05,400 --> 01:17:07,870 you could use that to move the endpoint. 1421 01:17:07,870 --> 01:17:12,600 So that's exactly dynamic segments, horizontal segments. 1422 01:17:12,600 --> 01:17:15,660 And then shooting a ray is-- 1423 01:17:15,660 --> 01:17:18,015 in general-- a general ray-shooting query 1424 01:17:18,015 --> 01:17:18,780 is like this. 1425 01:17:18,780 --> 01:17:20,670 I can be not from minus infinity, 1426 01:17:20,670 --> 01:17:24,840 be at an arbitrary point, and ask, what do I hit upward next? 1427 01:17:24,840 --> 01:17:29,259 That is like at this time doing a successor query. 1428 01:17:29,259 --> 01:17:31,050 OK, now this is a special kind of successor 1429 01:17:31,050 --> 01:17:33,224 query, because it's always from minus infinity. 1430 01:17:33,224 --> 01:17:34,890 So you might be able to solve it easier. 1431 01:17:34,890 --> 01:17:39,610 But in particular, you can solve it using this result. 1432 01:17:39,610 --> 01:17:43,710 So regular retroactivity helps you do nonoblivious 1433 01:17:43,710 --> 01:17:45,828 retroactivity. 1434 01:17:45,828 --> 01:17:46,328 Cool. 1435 01:17:53,090 --> 01:17:54,860 We're out of time. 1436 01:17:54,860 --> 01:18:00,686 So I will just say, the other cases are similar. 1437 01:18:00,686 --> 01:18:02,310 There's one other thing you need to do, 1438 01:18:02,310 --> 01:18:04,490 which is in addition to upward ray-shooting, 1439 01:18:04,490 --> 01:18:06,747 you have to do rightward ray-shooting because 1440 01:18:06,747 --> 01:18:07,580 of things like this. 1441 01:18:07,580 --> 01:18:09,020 If I delete this deletion, I want 1442 01:18:09,020 --> 01:18:10,394 to know what do I hit next. 1443 01:18:10,394 --> 01:18:11,810 So that's a rightward ray-shooting 1444 01:18:11,810 --> 01:18:13,730 among dynamic segments, which all happen 1445 01:18:13,730 --> 01:18:15,530 to start at minus infinity. 1446 01:18:15,530 --> 01:18:20,050 So it's again-- it's dynamic ray-shooting, or successor 1447 01:18:20,050 --> 01:18:23,450 queries, but in x instead of y. 1448 01:18:23,450 --> 01:18:25,310 So with those tricks, you can do all 1449 01:18:25,310 --> 01:18:27,410 of the cases of inserting deleting, 1450 01:18:27,410 --> 01:18:31,850 deleting insertions, inserting, all combinations 1451 01:18:31,850 --> 01:18:33,760 of those things.