201

(6 ответов, оставленных в Algo)

2rf пишет:

Хм, я слышал, что можно использовать не 3-разрядную, а где-то 8-разрядную арифметику + 64-битные целые числа; они конечно работают медленнее, чем 32-битные, но при этом и длина числа сокращается почти в 3 раза, т.е. в результате может получиться побыстрее.

С Фурье не получится 8 разрядную использовать, т.к. в промежуточных вычислениях будет переполнение. Там даже 4 разрядную вроде уже не выйдет. С 3 разрядной у меня работало правильно и быстро.

brainail пишет:

разве тут прокатит разбиение на разряды ??? я попробывал, ответ стало неверный выдавать, наверно коряво написал, да и от векторов похоуд нуна отказаться smile

Ну это то же самое, что ты возьмешь число не в системе счисления по основанию 10, а 100 или 1000. Суть от этого не поменяется, т.к. число все равно будет полиномом и к нему можно будет применить БПФ, просто у тебя цифр меньше выйдет.

202

(6 ответов, оставленных в Algo)

brainail пишет:

Я написал длинное умножение за n log(n) самым быстрым способом используя complex
Я не уверен что оно будет давать точный результат , это надо уточнить у автора, какая гарантия правильности ответа smile))
И второе,я пишу на Microsoft Visual C++ 2009, и на моей машине работает около 9 секунд,на двух числах длиной 5*10^5
То есть долговато,может это Си++ такое,я думаю если я напишу её на паскале,а я это сделаю скоро,то она будет работать < 5 секунд я думаю big_smile Может я в чём нибудь некорректен,и плохо написал что то,но у меня получается так.

Если писать для длинных чисел, то можно сделать трехразрядную длинную арифметику и тем самым ускорить программу.

203

(5 ответов, оставленных в Problems)

it4.kp пишет:

Числа в нижней строке имеют вид n*(n+1)/2
т.е мы за O(sqrt(n)) можем найти диагональ, ну а потом уже и все остальное за O(1)

Зачем за O(sqrt(n))?
Как минимум, тут можно бинпоиском с проверкой за O(1).

Но вообще, зная количество чисел на каждой диагонали(1,2,3,...), т.е. нам надо найти последнюю полную диагональ(такую которая лежит перед нашим числом). Получаем:

n*(n+1)<=a*2
n^2+n-a*2<=0

Решаем это неравенство и получаем номер диагонали за O(1).

204

(5 ответов, оставленных в Problems)

На первой диагонали у нас 1 число, на второй 2, на третьей 3 и т.д.. Значит мы можем найти номер диагонали на которой находится наше число(по формуле суммы членов арифм прогрессии). Так же мы можем найти первое число на нашей диагонали. Значит, мы знаем номер нашего числа в диагонали считая от левого верхнего. У первого числа на диагонали i координаты (1,i), у j-го (1+j-1,i+j-1).

205

(11 ответов, оставленных в Problems)

Да тут походу и макс. паросочетание прокатит...
Но если в плитках будет более двух клеток, то этот метод работать не будет.

206

(11 ответов, оставленных в Problems)

Всмысле для плиток 2*1 умеем? И как?

207

(11 ответов, оставленных в Problems)

Я почти уверен что потоком тут никак нельзя, т.к. поток может делиться, а следовательно, нам не удастся плитку положить сразу на несколько клеточек, не ломая ее.

208

(11 ответов, оставленных в Problems)

И как тут потоком?

209

(12 ответов, оставленных в Algo)

В этом куске кода:

forr(j,l,r) {
   w=f[j].x*a[i].x+f[j].y;
   if(w<fc || fc<0) { fc=w; l=j; } else break;
  }

Предполагается что если если A это номер участка f[j] в массиве a, то a(A).y=max(a(A).y,...,a(i).y), т.к. умножая на f[j].x мы умножаем на максимальную высоту участка от A до i. А почему тогда между A и i не может быть участка выше?

210

(12 ответов, оставленных в Algo)

Нет, я имею ввиду не это. В разборе они это как-то переписывают и избавляются в формуле перехода от этого максимума. Ведь для того чтобы сделать решение за О(Н) после сортировки, нужно привести переход к виду ans(i)=k*x+l. И этому максимуму тут не место.

211

(12 ответов, оставленных в Algo)

Спасибо за код. Избавление от ненужных это понятно. Я не могу понять как избавиться тут:

ans(i)=min(max(length[j],..,length[i])*width[i]+ans(j-1)) по всем 1<=j<=i

от

max(length[j],..,length[i])

212

(12 ответов, оставленных в Algo)

Я не понял псевдокода в разборе и вот мой вариант решения за квадрат:

Отсортируем все участки по возрастанию ширины. Идем слева направо. Пусть ans(i) это минимальная стоимость покупки всех участков с номерами от 1 до i(нумеруем с 1, а ans(0)=0).
Тогда получаем переход:

ans(i)=min(max(length[j],..,length[i])*width[i]+ans(j-1)) по всем 1<=j<=i

Как ускорить это решение до сложности O(NlogN) или даже O(N) после сортировки(как написано в разборе)?

213

(9 ответов, оставленных в Problems)

brainail пишет:

даже если под это условие что подпоследовательности , то нужна длинка что никак вроде не успеет .
Ну а так для ограничений поменьше самое простое это динамика за O(N^3) big_smile

Почему куб? Если без длинной арифметики(к примеру вывести ответ по какому-то модулю), то можно к примеру за O(NM).
f(i,j) это количество способов выбрать первые j символов строки s(в нужном порядке) в первых i символах text.
Тогда:
Если text(i)!=s(j), то f(i,j)=f(i-1,j)
Если text(i)==s(j), то f(i,j)=f(i-1,j)+f(i-1,j-1)

(long long)1

215

(3 ответов, оставленных в Problems)

Диаметр дерева находится так(без доказательства):
Выбираем любую вершину, пускаем от нее поиск в ширину. Затем выбираем вершину, которая находится на наибольшем удалении от стартовой вершины. Утверждается, что она будет одним из концов диаметра. Чтобы найти второй конец диаметра - запустим поиск в ширину от первого и выберем самую удаленную вершину от него.

Сложность выходит О(Н).

216

(17 ответов, оставленных в Problems)

Я не знаком с правилами отборов в команду России на межнар, но мне все же интересно, почему вместо участника занявшего четвертое место, в команду вошел пятый? Выходит, результаты РОИ не учитываются?

217

(5 ответов, оставленных в Problems)

Вместо сета лучше использовать priority_queue.

218

(15 ответов, оставленных в Algo)

Ну если просто находить максимум(т.е. только эта процедура), учитывая что обновление только в точке(как в данном случае), то что-то такое занимает немного места:

int findmax(int l,int r,int a,int b,int num)
{
 if (l==a && b==r-1) return MAX[num];
 if (b<(r+l)/2) return findmax(l,(r+l)/2,a,b,num*2); else
 if (a>=(r+l)/2) return findmax((r+l)/2,r,a,b,num*2+1); else
 return max(findmax(l,(r+l)/2,a,(r+l)/2-1,num*2),findmax((r+l)/2,r,(r+l)/2,b,num*2+1));
}

Ищет максимум на отрезке [a,b]
Вызывать findmax(0,RANGE,a,b,1)

219

(15 ответов, оставленных в Algo)

Ну как минимум, можно упростить эту реализацию используя обычный pair<int,int> и чтобы не засовывать в кучу отрицательное расстояние используя обычный оператор <, лучше объявить ее так:

priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > Q.

Тогда просто

pair<int,int> a=make_pair(dist,num); 
Q.push(a);

220

(2 ответов, оставленных в Problems)

Пусть D(t) - квадрат расстояния между кораблями в момент времени t. Tак как расстояние неотрицательно, то найдя минимум функции D(t) мы автоматически найдем минимум sqrt(D(t)).
X1(t) - x координата первого корабля в момент времени t.
X1(t)=x1 + t*dx1
Аналогично определим X2(t),Y1(t),Y2(t),Z1(t),Z2(t).
D(t)=sqr(X1(t)-X2(t))+sqr(Y1(t)-Y2(t))+sqr(Z1(t)-Z2(t))

Для начала рассмотрим тривиальные случаи:
1) Если D(t) - константа. В таком случае ответ 0.
2) Если D(t) возрастает на [0;+INF). Ответ опять таки 0.

Теперь будем считать, что искомое время t не равно 0.
Есть 2 способа решения этой задачи.

Способ 1:
Заметим, что D(t) - квадратичная функция с аргументом t. Найдя вершину параболы мы как раз и найдем минимум данной функции. Это решение дает точный ответ, но тут очень важно правильно раскрыть скобки и привести уравнение к нужному виду. Подозреваю у Вас ВА как раз из-за ошибки в формулах.

Способ 2:
Очевидно, что расстояние между кораблями вначале будет уменьшаться, а затем возрастать. Следовательно, мы можем применить троичный поиск по времени для поиска минимума функции D(t).

Вот приблизительный код решения(написано в браузере, так что не ручаюсь за то что нету багов):

inline double solve()
{
     double l=0.0,r=1e10;
     while (r-l>eps)
     {
          double t1=(2.0*l+r)/3.0,t2=(l+2.0*r)/3.0;
          if (D(t1)<D(t2)) r=t2; else l=t1;
     }
     return l;
}