这场题目设置有点问题啊,难度:Div.2 A->Div.2 B->Div.2 D->Div.2 C->Div.2 D->Div.1 D-> Div.1 E->Div.1 F简直有毒数组
只AC 4题彷佛就是1000+名了spa
这种考验手速的时刻Itst就比较擅长了,而后就红名+拿衣服了……code
若是最左边和最右边不一样就是$N-1$,不然就是中间跟两边颜色不一样的块到两边距离的最大值排序
代码ip
二分答案,对于一个二分值$mid$将全部要放的牛奶拿出来,每一次最高的和次高的放在一层get
代码it
注意到对任意$x \times y$的矩形作一次操做,等价于对这个矩形内全部$2 \times 2$的子矩形作一次操做,因而咱们只须要对$2 \times 2$的矩形作操做就能够了,这个直接从左往右、从上往下、要翻转就翻转就能够了io
代码test
题目至关于要求:有$n$条线段,左端点为$s_i$;$q$组询问,每一组询问每条线段的长度都为$l$,问线段覆盖总长度date
设$s_{i+1} = INF$,那么答案就是$\sum\limits_{i=1}^n \min{s_{i+1} - s_i , l}$。把全部$s_{i+1}-s_i$存下来排个序,每一次询问时二分
显然每一次选出的三角形的边长必定是$(2^i,2^i,2^j)$,其中$j \leq i$。因此能够从小往大贪心,每一次选择尽量多的三角形,即先把$< i$的剩下的木棒尽量地用掉,而后再3个3个地取当前剩余的木棒
先考虑对于一个$x$求答案。考虑树形DP。
设$val_u$表示$u$到它父亲的边的权值,设$f_{u , flag = 0/1}$表示对于$u$子树内的点除$u$之外度数都不超过$x$,且$u$的度数不超过$x+flag$时的最小代价。
转移考虑:对于一个点$v$,假设它的度数为$d_v(d_v > x)$,那么转移到$f_{v,1}$的状态中须要切掉$v$与其孩子的$d_v - x - 1$条边,而转移到$f_{v,0}$须要切掉$d_v - x$条边。而对于$y \in ch_v$,切掉边$(y,v)$意味着$f_v$从$f_{y,1}+val_y$转移,不然从$f_{y,0}$转移。因此初始默认答案为$\sum\limits_{y \in ch_v} f_{y,0}$,对于全部孩子按照$f_{y,1}+val_y-f_{y,0}$从小到大排序,选择前面若干条边切掉进行转移。
而后能够发现:$\sum\limits_{i=1}^n d_i = 2(n-1)$即$\sum\limits_{i=0}^{n-1}\sum\limits_{j=1}^n [d_i > j] = 2(n-1)$。因此若是称某一次询问中必需要切掉相邻的若干条边的点为重要点,则在全部询问中,重要点的总和为$2(n-1)$。
到这里不难想到虚树。对于每一次询问创建虚树。由于虚树上没法体现重要点与非重要点之间的边,可是实际有可能会切掉这样的边,因此对于每个重要点用一个堆维护它和它非重要点孩子之间的边的边权。DP过程当中,若是某个点$x$与虚树上$x$的孩子$y$在原树上的距离超过$2$,则直接用$\min(f_{y,0} , f_{y,1} + val_y)$转移$f_x$,不然像上面同样先默认转移$f_{y,0}$,而后把$f_{y,1} + val_y - f_{y,0}$丢进堆里,用堆求前若干小转移到$f_{x,0}$和$f_{x,1}$。
将询问从小到大作,就能够直接维护每一个重要点的非重要点儿子的堆。
Update:关于priority_queue,它的赋值操做彷佛跟元素个数有关(可是很是快?),大力赋值在菊花图上会TLE,因此要用multiset对操做进行撤销。
答案的下界是$\lceil \frac{\sum\limits_{i=1}^m hp_i}{n} \rceil$,而构造题通常都会取到这个下界(要否则怎么构造啊喂),因此考虑构造一种方式使得总攻击次数达到下界。那么咱们须要尽量少地浪费兵力,也就是说要尽量把全部敌人打到$0$血。
为了构造的方便,咱们令攻击方式为:先全部军队一块儿攻击第一个敌人,当第一个敌人的血量$<n$时,让一个前缀的军队攻击第一个敌人,让第一个敌人刚好达到$0$血,剩下的军队直接去攻击第二个敌人。维护前缀和$sum_i$,也就是说对于$\forall i \in[1,m)$,要存在一个前缀的军队,它们的人数之和为$sum_i \mod n$。不难想到一种可行方案:将全部$sum_i \mod n$排序获得数组$b_i$,$b_0 = 0 , b_m = n$,则$s_ i = b_i - b_{i-1}$。
构造方案直接暴力模拟上面的攻击方法。
一个暴力是$O(n2^kk)$的FWT,显然跑不过
显然地,对于三元组$A,B,C$,将其变为$0,A \oplus B , A \oplus C$,把最后结果的下标异或上$A$,这二者获得的结果等价。
那么在初始的数组中,$F_0 = a , F_{A \oplus B} = b , F_{A \oplus C} = c$,FWT以后每一个位置必定会是$a+b+c,a+b-c,a-b+c,a-b-c$中的一个。
设暴力FWT以后所有乘起来获得的某个位置的值为$(a+b+c)^x(a+b-c)^y(a-b+c)^z(a-b-c)^w$,解出$x,y,z,w$就可求出FWT结果。
首先$x+y+z+w=n$,而后任意给$(a,b,c)$赋值不会改变$x,y,z,w$的值,那么令$(a,b,c) = (0,1,0)$,将获得的$F$数组加起来FWT。由于FWT的和等于和的FWT,故有$(a+b+c)x + (a+b-c)y + (a-b+c)z + (a-b-c)w = p$,其中$p$就是FWT后获得的当前位置的值。对于$(a,b,c) = (0,0,1)$也作一遍。
如今有了$3$个方程,但$(a,b,c)=(1,0,0)(0,1,0)(0,0,1)$都出现过了,再取$(a,b,c)$都和这三个向量线性相关,因此要换一种思路。考虑数组$G$,$G[x] = \sum\limits_{i=1}^n [B_i \oplus C_i = x]$,对这个数组FWT,能够获得$x-y-z+w=q$,其中$q$是FWT完成以后的点值表示。
缘由大概是:设序列$F$FWT后的序列为$F'$,那么$F[b]$对$F'[a]$的贡献的系数是$(-1)^{count(a & b)}$,其中$count(x) = x$在二进制下$1$的个数,这个能够由FWT的式子获得。若是第$i$个三元组FWT以后第$j$位的值为$a-b+c$,那么有$2 \not\mid count((A \oplus B) & j) , 2 \mid count((A \oplus C) & j)$,即$2 \not\mid count((B \oplus C) & j)$,那么$F[B \oplus C]$对$F'[j]$的贡献就是$-1$,其他同理。
那么如今获得了$4$个方程组,能够求出点值表示,最后IFWT一下。
BONUS:能够利用与上面相似的方法解决更通常的对于$m$元组、$A,B,C < 2^k$的问题,复杂度约为$O(2^{m+k}(m+k)+nm)$。