https://qoj.ac/problem/8815
我们假设现在受到了一次攻击
那么我们就知道了后面可能攻击的集合
设当前可能被攻击的集合为S
设f(S)为对于这个集合下的期望值
记作cost1,cost2
cost1记作受攻击或付出代价
cost2实际上并不受到决策影响
对于cost2
取到每一个元素都是
1 ∣ S ∣ ∑ v ∈ S f ( S − { v } ) \frac{1}{|S|}\sum_{v\in S}f(S-\{v\}) ∣S∣1v∈S∑f(S−{v})
所以并不受决策影响
我们在决策中选较小值
枚举剩下的集合T, T ∈ S T\in S T∈S
概率为 ∑ T ∈ S 1 ( ∣ S ∣ ∣ T ∣ ) m i n { m , a v g { T } } \sum_{T\in S}\frac{1}{\binom{|S|}{|T|}}min\{m,avg\{T\}\} ∑T∈S(∣T∣∣S∣)1min{m,avg{T}}
只需要知道T的大小,做一个2维背包即可
https://acm.hdu.edu.cn/showproblem.php?pid=7437
我们先考虑x是偶数的情况
每次等概率选取字符,
设alice的串为a1,a2,a3…an/2
Bob的为b1,b2,b3…bn/2
那么我们现在交换a1,b1…我们发现概率不变
所以对于每一个a,b
那么pr[a>b] = pr[a<b]
= /-pr[a>b] = pr[a=b]
那么就转化成了求解a=b的概率,简单了很多
先认为每个字符的出现都是不同的
总排列数即n!
那么取到相同数的概率就是
1 n ! ( n / 2 ) ! ∏ c c n t c \frac{1}{n!}\frac{(n/2)!}{\prod_{c}cnt^c} n!1∏ccntc(n/2)!
(上式可能没抄全,慎看)
奇数下的情况可以类推
设n=2k+1
那么Alice一定取了k+1个
那么靠率前k个
考虑一个字符出现的情况为奇数
那么他在结尾
https://qoj.ac/problem/8819
(很简单啊这个题
先考虑在已有字符串中新加入一个字符
找到之前有没有一个字符和这个字符相等
寻找本质不同的子串数和加入后的
考虑前n个,通过询问n和n+1
确定一个前缀,我们二分一个位置
可以了解后半段和前半段出现的位置
前面的询问是已知的,
通过可以的任何字符串方法算就可以)什么叫任何的????
https://acm.hdu.edu.cn/showproblem.php?pid=7453
我们可以对时间进行扫描线
使用数据结构维护天数
瞬时速度为
v t = ∑ i = 1 n v t − 1 + v t 2 v_t = \sum_{i=1}^{n}\frac{v_{t-1}+v_t}{2} vt=i=1∑n2vt−1+vt
这样我们就可以维护每个顺势速度
假设对于当前的 v i − 1 , t v_{i-1},t vi−1,t,我们的目标速度是 g i , t g_{i},t gi,t
在这里从i-1到i速度发生变
我们维护每次加减
对于每一天,si,ti变化,那么si,ti相对的前后缀发生变化
在线段树上维护最大最小值
维护每一段加一减一即可
复杂度分析:
对于
∑
∣
v
i
,
t
−
v
i
−
1
,
t
∣
\sum|v_{i,t}-v_{i-1,t}|
∑∣vi,t−vi−1,t∣
每次找一段,都会使整个一段变化
共q次
复杂度O((n+m)logm)
https://codeforces.com/gym/105112/problem/B
先考虑一种不全相等的方案,
考虑直接排列,方案会不会是好的
考虑交叉点会不会重合
将分割点向后移动
考虑将最后一个与第一个交换
考虑对每几个集合,
可以拼接成某个大小,
如此合并,最终成为一个好的,
或者出现中间有相交的地方
只需要求解一个方案使得合法可能数尽量多
做一个背包,假设是一个宽度不同的多重背包
使用bitset优化,再做任意的背包即可
https://codeforces.com/gym/105139/problem/C
我们对图形砍若干刀,
使得变成规则的形状
对于一个形状,我们将所有凹进的角切掉即可
我们使整个矩形失去一部分
切出巨星的个数是内角和除以360
如果一次切到两个凹角,
那么就会减少一个
我们分析边数,发现线段数绝对不会超过顶点数
使用二分图)???
建边跑匹配
复杂度O(n^2)
https://www.luogu.com.cn/problem/CF1989F
只有来那种操作可以改变颜色
将一行转化为蓝色或红色
即 p r i > = p c j p_{ri}>=p_{cj} pri>=pcj和 p r i < = p c j p_{ri}<=p_{cj} pri<=pcj
那么进行连边
如果是同一个强连通分量
考虑分治
我们让他尽量递归到前面和后面
那么边就可以分为两类:
强连通分量内和强连通分量外
我们考虑在前半部分不需要合并,
只考虑后半段即可
那么我们对所包含的边都跑一遍强连通分量
复杂度线性
https://acm.hdu.edu.cn/showproblem.php?pid=7443
我们要确定mex的最大值,
就是使0-x尽量大
使用二分答案判断一条链上能否达到一个mex值
每个连通块内部就不会链接到其他点
开两维,需要办掉一些区域
我们化掉一些矩形,考虑删掉某个点所在的子树
那么还有一种情况,即连续几个点
使用线段树维护矩形面积并
对于每个图,连通块数量不会很多
那么树的数量就是n^2级别
(后面没听懂先不抄了。。)
https://acm.hdu.edu.cn/showproblem.php?pid=7436
使用线段树分治)????
当一个东西加入容易,
删除困难,
但可以撤销
那么线段树分治就很套路
我们将时间建一颗线段树
那么某条边就是在某段时间内存在
使用并查集加边
要满足撤销,就要使用按秩并查集
考虑是否是叶子,
递归到叶子时,
跟中要加的所有东西都加入了
时间认为是t,那么加到线段书上,应该是nlogt
总复杂度是O(fnlogt)
使用类似懒标记的方法,
对于每个叶子节点,
设置懒标记
考虑加边和减边
https://www.luogu.com.cn/problem/AT_abc363_g
如何在有修改的前提下进行操作
将题目看成类似费用流的关系
每一个点代表一天
发现一天只做一个工作,那么权值就是Ti
每次加一条边
维护整个费用流的图
套一个线段树分治
在n+q范围加边
最终出现边和反向边
所以一般情况下
每一个点,
都会有对应的一条边
向右有一定数量的反向边
往前流或往后流
我们去所有方案中权值的最大值
每次加一次边之需要一次增广
那么考虑维护增广结果
使用线段树维护
发现向后流的边会有反向边
能够从前面流的边,
一定会有反向的最大值
这样连边直到最后,只要加一减一就可以维护了
网络流学习笔记
最大流算法(Ford-Fulerson)
-
建立残差图(即残量网络图),初始化容量
-
在可以找到增广路的前提下循环:
a. 寻找增广路
b. 找到最小容量x
c. 更新残量网络上容量
d. 添加反向边
以下是Ford-Fulerson的不同实现
Edmonds-Karp
-
bfs寻找增广路
-
计算最小边,更新边权,添加反向边
-
得到新增广图
struct MF {
struct edge {
int v, nxt, cap, flow;
} e[N];
int fir[N], cnt = 0;
int n, S, T;
ll maxflow = 0;
int dep[N], cur[N];
void init() {
memset(fir, -1, sizeof fir);
cnt = 0;
}
void addedge(int u, int v, int w) {
e[cnt] = {v, fir[u], w, 0};
fir[u] = cnt++;
e[cnt] = {u, fir[v], 0, 0};
fir[v] = cnt++;
}
bool bfs() {
queue<int> q;
memset(dep, 0, sizeof(int) * (n + 1));
dep[S] = 1;
q.push(S);
while (q.size()) {
int u = q.front();
q.pop();
for (int i = fir[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
if ((!dep[v]) && (e[i].cap > e[i].flow)) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[T];
}
int dfs(int u, int flow) {
if ((u == T) || (!flow)) return flow;
int ret = 0;
for (int& i = cur[u]; ~i; i = e[i].nxt) {
int v = e[i].v, d;
if ((dep[v] == dep[u] + 1) &&
(d = dfs(v, min(flow - ret, e[i].cap - e[i].flow)))) {
ret += d;
e[i].flow += d;
e[i ^ 1].flow -= d;
if (ret == flow) return ret;
}
}
return ret;
}
void dinic() {
while (bfs()) {
memcpy(cur, fir, sizeof(int) * (n + 1));
maxflow += dfs(S, INF);
}
}
} mf;