UTPC2011

D:探索ゲーでpair<pair<int,int>,pair<int,int>>とかやるのつらいので、tupleを使う.勝手に辞書順が入ってるのでsetに入れられる

	using State = tuple<int,int,int,int>;
	queue<State> que;
	que.push({1,2,3,4});
	int a,b,c,d;
	tie(a,b,c,d) = que.front();
	cout<<a<<b<<c<<d<<endl;

E:
長さNの数列a,bがある、indexのリストを選んで、(prefix sum of a) ≤ bとなるようにせよ.という問題

まずどの順に選べばいいかが先にわかるというのが典型テク.連続する二つのswapを比べるとこの場合はbが小さい順がいいことがわかる.

なので今何個選んだかのDPで出来るんですけど、実はO(NlogN)になるらしい.

b昇順にするのまでは一緒、とりあえず貪欲に選ぶことにしていって、選んだ結果超えちゃったら、その時点でbが一番でかいやつを諦める(b昇順であることから諦めるのは高々一回であることがわかる).
証明:hoge

F:構成.帰納法

G:長さ選んで三角形→連続するように詰めれる

H:キャッシュ戦略→MCF.各sに対して[s,s+1)か[s,t)のどっちを選ぶか決められるんだけど、はじめ全部ちっちゃい方を選んでいると思うと、[s+1,t)を選んで重なりがf-1個 とみなせる,かなり特殊っぽい

I:(x==3)みたいな式が書きたいんだけど、これは(x==4)みたいな2冪にたいしてできれば良くて、でも冷静に考えるとこれはできないことがわかる,ちゃんというと、xの上の桁がyの下の桁に影響をおよぼすことは絶対にない.
なので出力のi桁目を決めるときは入力の0~i桁目を使えば良くて、(x==3?8:0)みたいなのは簡単にかけるのでOK.

J:まずN!通りのうちの数え上げになる.優先度順に見れば単純に二分木に挿入するだけになる.根が何番目か決めることでO(N^3)のDPができる.更新部分が畳み込みなのでO(N^2logN)にできる.hがでかいとこはどうせほぼ0なので、O(Nlog^2N)にできる.double版多項式まともに作ってなかった・・・

K:M≤N+500 圧縮です

L:永続