2019.11.4模拟赛
T1 奇因数之和
定义\(F(n)\)为\(n\)的最大奇因数,例如\(F(1) = 1\),\(F(6) = 3\),\(F(12) = 3\)。
输入\(m\),求\(\sum\limits_{i = 1}^{m}F(i)\)。
\(m \leq 10^{100}\)
分析一下我们发现,如果\(i\)是偶数,\(F(i) = F(i / 2)\),这样的话就可以分治求了。
这题难度在高精,谁考场上写大高精啊
r = open('sigma.in','r')
w = open('sigma.out','w')
ans = 0
def sove(*t):
global ans
x = int(t[0])
if x == 0:
return None
if x % 2 == 1:
ans += (x + 1) * (x + 1) // 4
else:
ans += x *x // 4
sove(x // 2)
n = r.read()
sove(n)
w.write(str(ans))
当然可以不递归求
r = open('sigma.in', 'r')
w = open('sigma.out', 'w')
ans= 0
n = int(r.read())
while(n != 0):
if(n & 1):
ans += (n + 1) * (n + 1) // 4
else:
ans += n * n // 4
n //= 2
w.write(str(ans))
以下是c++的代码。高精类过大没有放。
高精类模板
signed main()
{
freopen("sigma.in", "r", stdin);
freopen("sigma.out", "w", stdout);
GNUM n;
GNUM zero(0);
cin >> n;
GNUM ans(0);
while (!(n == zero))
{
if (n.opd())
ans = ans + (n + 1) * (n + 1) / 4;
else
ans = ans + n * n / 4;
n = n / 2;
}
cout << ans << endl;
return 0;
}
T2 激光塔阵
小强的激光塔阵共有\(P\)座激光塔,它们被建造在一个$N \times M \(的矩形网格上。每座激光塔都有自己的坐标\)(x,y)\(,其中\)x(1 \leq x \leq n)\(和\)y(1 \leq y \leq m)\(均为整数。当两座激光塔的\)x\(坐标和\)y\(坐标至少一个相同时,这两座塔就可以产生联系。若激光塔\)A\(与\)B\(有联系,\)B\(与\)C\(也有联系,则可以认为\)A\(与\)C$也有联系。但是现在激光塔并不一定两两都有联系,所以他想新建一些新的激光塔使得激光塔两两都有联系。
你要计算并输出小强最少需要建造多少个激光塔。
显然并查集维护一下有几个连通块就可以了。
int main()
{
freopen("laser.in", "r", stdin);
freopen("laser.out", "w", stdout);
poread(n), poread(m), poread(p);
for(register int i = 1; i <= p; ++i)
poread(data[i].x), poread(data[i].y), data[i].id = i;
for(register int i = 1; i <= p; ++i)
fa[i] = i;
sort(data + 1, data + 1 + p, cmp1);
for(register int i = 2; i <= p; ++i)
{
if(data[i - 1].x == data[i].x)
{
register int x = find(data[i - 1].id), y = find(data[i].id);
if(x == y)
continue;
fa[y] = x;
}
}
sort(data + 1, data + 1 + p, cmp2);
for(register int i = 2; i <= p; ++i)
{
if(data[i - 1].y == data[i].y)
{
register int x = find(data[i - 1].id), y = find(data[i].id);
if(x == y)
continue;
fa[y] = x;
}
}
register int ans = 0;
for(register int i = 1; i <= p; ++i)
{
if(find(i) == i)
{
++ans;
}
}
printf("%d", ans - 1);
}
T3 深入虎穴
这题是个语文题不放题面了。大概就是每次求次短路都从次短路进行转移。
只放垃圾跑的贼慢的\(spfa\)了。
inline void sspfa()
{
queue<int> q;
memset(d, 0x3f, sizeof(d));
memset(md, 0x3f, sizeof(md));
for(register int i = 1; i <= k; ++i)
{
d[ek[i]] = md[ek[i]] = 0;
g[ek[i]] = mg[ek[i]] = ek[i];
q.push(ek[i]);
v[ek[i]] = 1;
}
while(q.size())
{
register int x = q.front();
q.pop();
v[x] = 0;
for(register int i = head[x]; i; i = e[i].nxt)
{
register int y = e[i].ver;
if(d[y] > md[x] + e[i].edge)
{
if(g[y] != x)
md[y] = d[y], mg[y] = g[y];
d[y] = md[x] + e[i].edge;
g[y] = x;
if(!v[y])
q.push(y), v[y] = 1;
}
else if(md[y] > md[x] + e[i].edge && g[y] != x)
{
md[y] = md[x] + e[i].edge;
mg[y] = x;
if(!v[y])
q.push(y), v[y] = 1;
}
}
}
}