题面

有 n 个学生和 n 所大学,每个学生在其中一所大学中学习,且各有一个能力值

s

i

s_i

si​ 。

某次组队打比赛的召集令会给一个数字 k ,表示团队数量。然后每所大学会先把自己的所有学生按照

a

i

a_i

ai​ 从大到小排序,选前

k

k

k 个组个队,前

k

+

1

k+1

k+1 到

2

k

2k

2k 个组个队,……剩下最后不足

k

k

k 个学生,这些学生就不能组队。

每次召集的总能力值为所有组出来的队伍的每个学生的能力值之和。现在有

n

n

n 次召集令,给出的

k

k

k 分别是 1~n,分别求每次召集的总能力值。

题解

我这个做法被 nlogn 做法吊打,本愧于过此题,然所用方法有点思维,不如写来搏之一笑。

分别求每个学生的贡献。

假设当前学生在他(她)的大学里排名为倒数第

y

y

y ,而大学里总共

x

x

x 个学生,那么该学生对数字为

k

k

k 的召集令有贡献当且仅当

x
 ⁣ ⁣ ⁣ ⁣

m

o

d

  

k

<

y

x\!\!\!\!\mod k<y

xmodk<y
变一下式子:

x

x

k

k

<

y

x

y

<

x

k

k

x

y

k

<

x

k

x-\left\lfloor \frac{x}{k}\right\rfloor*k<y\\ ~~\Leftrightarrow~~ x-y<\left\lfloor \frac{x}{k}\right\rfloor*k\\ ~~\Leftrightarrow~~ \left\lfloor \frac{x-y}{k}\right\rfloor<\left\lfloor \frac{x}{k}\right\rfloor

x−⌊kx​⌋∗k<y  ⇔  x−y<⌊kx​⌋∗k  ⇔  ⌊kx−y​⌋<⌊kx​⌋

如果我们已知

x

k

=

d

\left\lfloor \frac{x}{k}\right\rfloor=d

⌊kx​⌋=d,那么

x

y

k

<

d

x

y

<

d

k

x

y

d

<

k

\left\lfloor \frac{x-y}{k}\right\rfloor<d\\ ~~\Leftrightarrow~~ x-y<dk\\ ~~\Leftrightarrow~~ \left\lfloor \frac{x-y}{d}\right\rfloor<k

⌊kx−y​⌋<d  ⇔  x−y<dk  ⇔  ⌊dx−y​⌋<k

好,这是个关于

k

k

k 的范围的表达式了,由于我们知道

x

k

\left\lfloor \frac{x}{k}\right\rfloor

⌊kx​⌋ 随着

k

k

k 的不同只有大约

x

\sqrt x

x

​ 个取值,因此我们可以数论分块枚举,每次枚举到一个区间

[

l

,

r

]

[l,r]

[l,r] 和

d

d

d,就对答案序列的

[

max

(

x

y

d

+

1

,

l

)

,

r

]

[\max(\left\lfloor \frac{x-y}{d}\right\rfloor+1,l),r]

[max(⌊dx−y​⌋+1,l),r] 产生贡献。

对每个学生都计算一次,复杂度

O

(

n

n

)

O(n\sqrt n)

O(nn

​)。

CODE

#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 200005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
int a[MAXN];
vector<int> u[MAXN];
LL sm[MAXN];
bool cmp(int x,int y) {return a[x] > a[y];}
int main() {
int T = read();
while(T --) {
n = read();
for(int i = 1;i <= n;i ++) u[i].clear(),sm[i] = 0;
for(int i = 1;i <= n;i ++) {
s = read(); u[s].push_back(i);
}
for(int i = 1;i <= n;i ++) {
a[i] = read();
}
for(int i = 1;i <= n;i ++) {
sort(u[i].begin(),u[i].end(),cmp);
int X = u[i].size();
for(int j = 0,nm = X;j < (int)u[i].size();j ++,nm --) {
int con = a[u[i][j]];
sm[1] += con; sm[nm+1] -= con;
for(int l = nm+1,r = 1;l <= X;l = r+1) {
r = X/(X/l); int d = X / l;
int ll = max(l,((X-nm)/d) + 1);
if(ll <= r) {
sm[ll] += con; sm[r+1] -= con;
}
}
}
}
for(int i = 1;i <= n;i ++) {
sm[i] += sm[i-1];
printf("%lld ",sm[i]);
}ENDL;
}
return 0;
}

[CF1519C] Berland Regional (数论分块)的更多相关文章

  1. 【BZOJ1257】余数之和(数论分块,暴力)

    [BZOJ1257]余数之和(数论分块,暴力) 题解 Description 给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + - + k mod n的 ...

  2. 51nod“省选”模测第二场 B 异或约数和(数论分块)

    题意 题目链接 Sol 这题是来搞笑的吧.. 考虑一个数的贡献是\(O(\frac{N}{i})\) 直接数论分块. #include<bits/stdc++.h> #define Pai ...

  3. 洛谷P2261 [CQOI2007] 余数求和 [数论分块]

    题目传送门 余数求和 题目背景 数学题,无背景 题目描述 给出正整数n和k,计算G(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod ...

  4. luoguP3235 [HNOI2014]江南乐 数论分块 + 博弈论

    感觉其实很水? 题目就是一个Multi SG游戏,只需要预处理出所有的\(sg\)值即可\(O(Tn)\)计算 对于计算\(sg[n]\)而言,显然我们可以枚举划分了\(x\)堆来查看后继状态 那么, ...

  5. bzoj 3834 [Poi2014]Solar Panels 数论分块

    3834: [Poi2014]Solar Panels Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 367  Solved: 285[Submit] ...

  6. 洛谷P1403 [AHOI2005] 约数研究 [数论分块]

    题目传送门 约数研究 题目描述 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机“Samuel II”的长时间运算成为了可能.由于在去年一年的辛苦工作取得了不错的成绩, ...

  7. 「BZOJ 2440」完全平方数「数论分块」

    题意 \(T\)组数据,每次询问第\(k\)个无平方因子的数(\(1\)不算平方因子),\(T\leq 50,k\leq 10^9\) 题解 \(k\)的范围很大,枚举肯定不行,也没什么奇妙性质,于是 ...

  8. bzoj 1257 余数之和 —— 数论分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1257 \( \sum\limits_{i=1}^{n}k\%i = \sum\limits_ ...

  9. 【数论分块】bzoj2956: 模积和

    数论分块并不精通……第一次调了一个多小时才搞到60pts:因为不会处理i==j的情况,只能枚举了…… Description $\sum_{i=1}^{n}\sum_{j=1 \land i \not ...

随机推荐

  1. c++ 超大整数除法 高精度除法

    c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...

  2. 【Github】 Github修改仓库的基本信息

    前言 我们通常在刚开始了解学习使用github时,一般都是测试的使用,有时我们向里面添加了一些代买,如果想要修改信息并且是删除仓库重新创建提交,可以采用下面方法修改仓库信息,名称.描述等. 修改仓库描 ...

  3. BUUCTF-BJDCTF2020]just_a_rar

    BJDCTF2020]just_a_rar 压缩包提示是四位数密码 爆破得知压缩包密码 16进制查看解压的图片后发现flag flag{Wadf_123}

  4. ABAP CDS - Language Elements

    The following sections summarize the language elements of the DDL and DCL of the ABAP CDS, arranged ...

  5. IDEA中Maven Project所在位置

    难免有小伙伴找不着这个在哪. 一.首先就是可以在下面这个位置查询到: 二.如果找不着,那么在这里找: 三.如果还找不到,那就没有是你刚导入的项目没有Add Maven, 下面这个图是我Add  Mav ...

  6. 基于UniApp社区论坛多端开发实战

    什么是移动端WebApp 移动端WebApp: 泛指手持设备移动端的web 特点: - 类App 应用,运行环境是浏览器 - 可以包一层壳,成为App - 常见的混合应用: ionic, Cordov ...

  7. 代码补全——Vim/Neovim中YouCompleteMe添加第三方库的支持

    参考链接: https://github.com/ycm-core/YouCompleteMe#c-family-semantic-completion https://cloud.tencent.c ...

  8. BUCK 电路PSIM仿真模型搭建之一 (PI模块稳定性分析)

    1.  利用PI 模块仿真BUCK 电路电流环 在调制通道上未加入延迟环节时,无论KP, KI 参数如何调整系统都是稳定的 仿真结果: 在调制通道上引入 一个开关周期的延迟 系统出现明显的震荡情况,说 ...

  9. CF1702B Polycarp Writes a Srting from Memory 题解

    给定一个字符串,每天可以记忆三个字符,求书写出整个字符串的天数. 每次确定要记忆的三个字母,并向后寻找,若有非三个字母其中一个,则重新开启一天记忆三个字母. #include<cstdio> ...

  10. Pandas简单操作(学习总结)

    Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),是一个提供高性能.易于使用的数据结构和数据分析工具. 接下来查看Pandas的基本使用: # 导入模块 i ...