BZOJ 4369: [IOI2015]teams分组】的更多相关文章

把一个人看成二维平面上的一个点,把一个K[i]看成左上角为(0,+max),右下角为(K[i],K[i])的一个矩阵,那么可以很好地描述人对于询问是否合法(我也不知道他怎么想到这东西的) 然后把一组询问排序,按照K[i]从小到大依次处理,定义一个取点的方式为尽量取纵坐标小的点,那么可以构造出一种方案使得对于每一块区域不能取的点的最大纵坐标递减 (我也不知道他怎么想到这东西的) 单调栈维护每一块被取过的点的最大纵坐标,那么随着K[i]的增大,区域会被合并 二维平面数点,主席树 #include<c…
将分组计划按照$k$从小到大排序,维护一个单调栈,每个元素为一个矩形,按最底下元素从高到低排列,栈顶最低. 每次加入一个矩形可选区域,维护单调栈,可以往回合并. 然后将所有最低点不满足的矩形取出,合并后放回. 每次考虑栈顶区域,将它取到和下一个矩形底边一致时合并. 可持久化线段树维护,时间复杂度$O((n+s)\log n)$. #include<cstdio> #include<algorithm> const int N=500010,M=200010,P=N*20; int…
[BZOJ 2989]数列(二进制分组+主席树) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Modify x k:将第x个数的值修改为k. 2.Query x k:询问有几个i满足graze(x,i)<=k.因为可持久化数据结构的流行,询问仅要考虑当前数列,还要考虑任意历史版本,即统计任意位置上出现过的任意数值与当前的a[x]的graze值<=k…
题目 似乎很久没写题解了... 这题是校里胡策的时候的题,比赛因为评测机有点慢+自己代码常数大没快读...被卡t了,但是bzoj上还是A了的...,因为bzoj时限比较宽可以不卡常. 题解: 首先可以发现答案与操作顺序是无关的,也就是说,可以钦定答案就是x次操作,然后让先手的x次先全换了,然后再考虑我要怎么换,才能在最少次数内换成升序. 于是就可以直接枚举答案x,然后判一下x是否可行. 考虑如何判断,问题会变成,给定一个a序列,每次可以交换两个数,问最少交换多少次可以换成升序,也就是变成a[i]…
跑了7000ms... 这是个体积和价值都超大的背包.但是体积保证为a*2^b的(a<=10,b<=30)形式.且n<=100. 于是可以想到按b来分组.这样的话每组最多为a*n*2^b的体积.把每个分组进行一次01背包. 令dp[i][j]表示体积为j*2^i+w&(1<<i)的最大价值.再把每个分组背包做一次01背包,随便转移一下就行了. # include <cstdio> # include <cstring> # include &l…
刚开始往网络流的方向想.建不出图... 因为每次只能对一行进行染色.每一行都是独立的. 对于每一行,因为格子只能染一次,所以可以发现这是一个多阶段决策问题,这个决策就是当前格子染0还是染1. 令dp[i][j][k](k==0||k==1)表示当前行第i个格子用了j次染色,且这次染色染为k色 的最多有效格子. 这样我们用了O(n*m*m)得出了每一行用了v次染色获得的最多有效格子val. 显然的分组背包.每一个组最多选一种.再用O(V*n*m)求一遍分组背包即可. 总复杂度O((V+m)*m*n…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 如果枚举1号点走哪些点出去,就从那些点出发跑多源最短路即可.最短路不会重复经过一条边. 怎样枚举较优?需要枚举到答案的起点在一组.终点在另一组:考虑按点的编号二进制分组,即枚举每一位,为0的在一组,为1的在另一组. 因为两个点编号不同,所以二进制表示至少有1位不同,即任意两个点一定一度被分到过两个组里. 好像还有构造新图的更快的做法.不过也没管. #include<iostream>…
思路: $(x_0-x)^2+(y_0-y)^2<=x^2+y^2$ $y>=(-x_0/y_0)x+(x_0^2+y_0^2)/2y0$ 这显然就是凸包了 以一个斜率不断向下(上)走  找到第一个接触到的点 离线可以用cdq分治一发 他左边的判一判是不是都符合在圆内 这不能离线就很难搞了 感觉自己代码能力捉鸡   写棵splay估计要调死 强烈安利二进制分组做法 非常强 在log个凸包上 二分一下斜率 判一判 就好了 //By SiriusRen #include <bits/stdc…
三种路径,左边出去左边回来,右边出去右边回来,绕一圈 绕一圈的路径最多出现一次 那么绕一圈的路径覆盖的点一定是左边半圈的右边和右边半圈的左边 枚举绕一圈的路径的起始点(一定要枚举,这一步不能贪心),更新答案 #include<cstdio> #include<algorithm> using namespace std; int a[10000005],X[10000005],Y[10000005]; long long L[10000005],R[10000005]; bool…
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4398 按二进制每一位是 0/1 把 1 号点的儿子分成两组,分别作为起点和终点跑多起点最短路,最优解的起点和终点总有一次会被分到不同组里: 太久没写 dijkstra 竟然WA了4次...别忘了 priority_queue 是大根堆-_-,还要注意循环计数的 i,j 不要重了... 代码如下: #include<iostream> #include<cstdio> #inc…