Gravatar
yrtiop
积分:2121
提交:315 / 821

发现最难受的是每行必须选最大值,不好统一刻画。

但是我们可以直接转化这个问题:泛化为从每行选一个数,求最大可能值。不难发现这样答案不会变化。

于是可以状压 dp,$f(i,S)$ 表示处理完前 $i$ 列,目前 $S$ 中为 $1$ 的行已经选上数的最大可能值。

转移直接枚举循环位移,然后枚举子集转移即可。$\mathcal O(Tmn3^n)$。

再做一些最优性的分析,加以预处理,可以做到 $\mathcal O(T(m\log m + n^32^n + n3^n))$。


题目3249  Rotate Columns      7      评论
2024-05-24 16:45:08    
Gravatar
GS53
积分:48
提交:17 / 66

//阅读须知:请读完第六行后跳到主函数阅读,有利于理解程序。

//思路:建立一个最大为n/2+1的小根堆,将数据输入小根堆,若堆满就删除堆顶元素,直到数据全部输入。

//若n为偶数,则中位数为堆顶元素,否则中位数为堆顶元素与左孩子和右孩子间更小的那个元素的算数平均值,即(堆顶元素+左孩子与右孩子间更小的那个)/2

#include<iostream>

#include<cstdio>

using namespace std;

int a[260000]; //定义小根堆a

int n,s=0,b,t;//n:需处理数据数量,s:堆内元素数量,b:输入媒介(数据中转),t:未处理数据数量

void swim(int s)//上浮操作,变量s为需要进行上浮的数据,本函数用于插入

{

while(s>1&&a[s]<a[s/2])

{

swap(a[s],a[s/2]);

s/=2;

}

}

void push(int b)//插入数据

{

a[++s]=b;

swim(s); //此处s为要上浮的元素在堆中的下标,详见上浮函数swim

}

void jd()//建立小根堆a,此时a中包含了输入数据中前n/2+1个数据

{

   for(int i=1;i<=n/2+1;++i)

   {

       cin>>b;

       push(b); //将b插入至堆中,详见插入函数push

   }

}

void sink(int k)//下沉操作,k恒为1

{

while(2*k<=n/2+1)

   {

   int j=2*k;

   if(j+1<=n/2+1&&a[j]>a[j+1])

   {

       j=j+1;

   }

   if(a[k]<=a[j])

   {

       break;

   }

   swap(a[k],a[j]);

   k=j;

   }

}

void pop()//删除数据

{

   a[1]=a[s--]; //将堆顶替换为堆底元素

   sink(1);

}

int main()

{

   freopen("median.in","r",stdin);

   freopen("median.out","w",stdout);

   cin>>n;

   jd(); //建堆,详见建堆函数jd

   t=n-(n/2+1); //计算未处理数据数量,以免在循环里计算导致超时

   while(t) //当数据没有处理完时

   {

       t--; //剩余数据-1

       cin>>b;

       push(b); //将输入数据b插入堆中,详见插入函数push

       pop(); //将堆顶(下标最小的不可能为中位数的元素)删除,详见删除函数pop

   }

   if(n%2) //当n为奇数

   {

       printf("%0.1f\n",1.0*a[1]);

   }

   else

   {

       printf("%0.1f\n",1.0*(a[1]+min(a[2],a[3]))/2.0);

   }

   return 0;

} //Adam与GS53热心创作



题目1699  中位数 AAAAAAAAAAAAAAAAAAAA      8      评论
2024-05-14 21:32:50    
Gravatar
┭┮﹏┭┮
积分:4448
提交:907 / 1937

杜教筛

求 $\sum_{i=1}^{n} \phi(i^2)$

基本上是裸的杜教筛

一个关于 $\phi$ 的性质:$$\phi(ij) = \frac{\phi(i)\phi(j)gcd(i,j)}{\phi(gcd(i,j))}$$

证明:该式本质上是容斥,$\phi$ 的原式子是,当 $n = {p_1}^{c_1}\times {p_2}^{c_2} \times ··· \times {p_m}^{c_k}$

$\phi(n) = n \times \prod_{i=1}^{m} (1 - \frac{1}{p_i})$

这里式子就表示为先把 $i$ 和 $j$ 的质因数乘上在除去 $i,j$ 的共同质因数,即 $\phi(gcd(i,j))$,最后再消掉 $gcd(i,j)$ 即可得到该式。

然后开始推式子:

$$ \sum_{i=1}^{n} \phi(i^2) = \sum_{i=1}^{n} i \times \phi(i) $$

不难发现该式等于 $\phi \cdot id$

$$ (\phi \cdot id) \ast id = \sum_{d\mid n} d * \phi(d) * \frac{n}{d} = n \times \sum_{d\mid n} \phi(d) = id^2$$

我们设 $f(n) = n \times \phi(n),S(n) = \sum_{i=1}^{n} f(i)$ ,这里的 $id$ 与 $id^2$ 的前缀和都比较好求。

运用杜教筛公式可得:

$$ S(n) = \sum_{i=1}^{n}i^2 - \sum_{i=2}^{n} i * S(\lfloor\frac n i\rfloor)$$

$$ = \frac{n(n+1)(2n+1)}{6} - \sum_{i=2}^{n} i * S(\lfloor\frac n i\rfloor)$$

线性筛出前 $n^{\frac{2}{3}}$ 项,整除分块即可





题目3352  平方前缀和 AAAAA      11      评论
2024-04-06 15:38:46    
Gravatar
yuan
积分:1083
提交:417 / 673

题目3827  举办乘凉州喵,举办乘凉州谢谢喵      6      评论
2024-04-03 12:11:51    
Gravatar
op_组撒头屯
积分:3069
提交:344 / 684

幸せな明日を願うけど 底なしの孤独をどうしよう

もう うめき声しか出ない  わたし ぎゅうぐらりん


强度最低的一集。

考虑一个点 $(p_1,...,p_k)$ 的距离应该怎么算。

不难发现只可能是他们奇/偶最短路的最大值。也就是在距离最大的点到达前,其他所有的点都在某条边上来回横条。

记 $f_{u,0/1}$ 表示点 $u$ 的偶/奇最短路,那么答案就是

$$\sum_{S=\{p_1,...,p_k\}}{\min(\max_{u\in S}(f_{u,0}),\max_{u\in S}(f_{u,1}))}$$

既有min又有max,不是很好算。考虑min-max容斥,则答案为

$$\sum_S{\max_{u\in S}(f_{u,0})}+\sum_S{\max_{u\in S}(f_{u,1})}-\sum_S{\max_{u\in S}(\max(f_{u,0},f_{u,1}))}$$

注意到三者完全等价,我们只考虑第一项。

考虑将 $u$ 按 $f_{u,0}$ 升序排序后依次扫,那么问题转化为:

每次往某个组加入一个点,求从每个组中各选出一个点的方案数。

预处理逆元,容易做到线性复杂度。


题目3559  [USACO21Jan Platinum]Sum of Distances      9      评论
2024-03-29 22:04:35    
Gravatar
小金
积分:1886
提交:309 / 580

观察题图可知,一个骑士能攻击到的格子与自己所在的格子异色,所以有一种摆法是都摆在同一颜色的格子上,把一条相互攻击的关系变为网络流路径,这样就将扔掉骑士转化为了求最小割

因为一个骑士能与多个骑士互相攻击,所以可以共用路径

建图如下:

·源点向每个黄格子连边,流量为1

·每个黄格子向能攻击到的红格子连边,流量为∞

·每个红格子向汇点连边,流量为1

跑最大流求出最少扔掉几个骑士,答案为n^2−m−maxflow



题目746  [网络流24题] 骑士共存 AAAAAAAAAA      6      评论
2024-03-29 21:56:51