早上水了场LuoGu月赛
T1:终于结束的起点
跟斐波那契数列有关的题目,刚读完题面的我其实是有些懵逼的,(什么鬼?是不是又要来一波很长很长的推导?)几分钟后发现暴力可以解决、
好兴奋啊qwq,码了发暴力,又把数据范围内的m都打表试了一遍,没有Tle,开开心心的提交了
预计得分:100 实际得分:100
Code:
var
f : array[0..10000000] of longint;
m, i : longint;
begin
readln(m);
f[0] := 0; f[1] := 1 mod m;
for i := 2 to 100000000 do
begin
f[i] := (f[i - 2] + f[i - 1]) mod m;
if (f[i - 1] = 0) and (f[i] = 1) then
begin
writeln(i - 1);
halt;
end;
end;
end.
T2:跳跳!
看完题目,感觉是道dp题,然后发现dp有些不可做,凭借我以往月赛只会T1的经历,差点弃疗码20分暴搜了
身边的czx和nn颓起了slay,我有点按耐不住了!!!
突然发现,是一道小贪心,你当前站在0这个位置,只要先跳到最高的,再跳到最低的,再跳到剩下的最高的,再跳到剩下的最低的……
在草稿纸上随便搞了搞就搞出来了,兴奋啊,决定码完 T2颓slay了
预计得分:100 实际得分:100
证明略
Code:
var
a : array[0..100000] of int64;
ans, h : int64;
n, i, j : longint;
procedure sort(l, r : longint);
var
i, j, mid, tmp : int64;
begin
i := l; j := r; mid := a[(l + r) >> 1];
repeat
while a[i] < mid do inc(i);
while a[j] > mid do dec(J);
if i <= j then
begin
tmp := a[i]; a[i] := a[j]; a[j] := tmp;
inc(i); dec(j);
end;
until i > j;
if i < r then sort(i, r);
if l < j then sort(l, j);
end;
begin
readln(n);
for i := 1 to n do read(a[i]);
sort(1, n);
i := 1; j := n;
h := 0;
while i <= j do
begin
inc(ans, sqr(h - a[j]));
if i <> j then inc(ans, sqr(a[i] - a[j]));
h := a[i];
inc(i); dec(j);
end;
writeln(ans);
end.
T4:不围棋
颓了几把slay后,发现T4的提交比T3多,以为T4更简单,就先做起了T4
感觉不是很好做,暴力的话也是有点麻烦,想到一个O(n^6)的,满脑子都是slay的我放弃了暴力,突然发现有三个数据棋盘为空
嘿嘿,可以骗分了
码了个骗分程序,提交了
继续颓slay去(slay惊现Holy_Aush!)
预计得分:30 实际得分:33
Code:
var
n, i, j : longint;
begin
readln(n);
if n and 1 = 1 then
begin
for i := 1 to n >> 1 do
for j := 1 to n do
begin
writeln(i, ' ',j);
writeln(n + 1 - i, ' ', j);
end;
for i := 1 to n >> 1 do
begin
writeln((n >> 1) + 1, ' ', i);
writeln((n >> 1) + 1, ' ', n + 1 - i);
end;
writeln('-1 -1');
end else
begin
for i := 1 to (n >> 1) - 1 do
for j := 1 to n do
begin
writeln(i, ' ',j);
writeln(n + 1 - i, ' ', j);
end;
for i := 1 to n - 1 do
begin
writeln(n >> 1, ' ', i);
writeln((n >> 1) + 1, ' ', i);
end;
writeln(n >> 1, ' ', n);
writeln('-1 -1');
end;
end.
后续的部分分+正解我没怎么听懂,嗯不说了
T3:咕咕咕
czx一直在旁边说状压,11点我恋恋不舍得从slay退了出来,看完题目,发现状压可以水,估计会Tle几个点,开始水状压
说好的11:30放呢?人都走了,只剩我们几个了,过了样例1,样例2爆掉了,算了提交吧
预计得分:0 实际得分:10
Code:
uses math;
const
p = 998244353;
var
pow, dp : array[0..2000000] of int64;
i, j : longint;
ch : char;
n, m, x, y, s : int64;
begin
readln(n, m);
pow[0] := 1;
for i := 1 to n + 1 do pow[i] := pow[i - 1] << 1;
for i := 1 to m do
begin
x := 0;
for j := 1 to n do
begin
read(ch);
inc(x, (ord(ch) - 48) * pow[n - j]);
end;
readln(ch, y);
dp[x] := (dp[x] + y) mod p;
end;
for i := 1 to pow[n] - 1 do
begin
s := i;
while true do
begin
s := (s - 1) and i;
dp[i] := (dp[s] + dp[i]) mod p;
if s = 0 then break;
end;
end;
writeln(dp[pow[n] - 1]);
end.
70分,状压dp
晚上听讲解,发现上午的我真s b,把状态转移方程改一改就好了
c
n
t
[
i
]
表
示
状
态
i
有
几
种
方
案
cnt[i]表示状态i有几种方案
cnt[i]表示状态i有几种方案
s
u
m
[
i
]
表
示
状
态
i
的
歉
意
值
总
和
sum[i]表示状态i的歉意值总和
sum[i]表示状态i的歉意值总和
a
[
i
]
表
示
状
态
i
的
歉
意
值
a[i]表示状态i的歉意值
a[i]表示状态i的歉意值
c
n
t
[
i
]
=
∑
j
i
c
n
t
[
j
]
(
j
∈
i
)
cnt[i]=\sum_{j}^{i}cnt[j](j∈i)
cnt[i]=∑jicnt[j](j∈i)
s
u
m
[
i
]
=
∑
j
i
s
u
m
[
j
]
(
j
∈
i
)
+
c
n
t
[
i
]
∗
a
[
i
]
sum[i]=\sum_{j}^{i}sum[j](j∈i)+cnt[i]*a[i]
sum[i]=∑jisum[j](j∈i)+cnt[i]∗a[i]
Code:
const
p = 998244353;
var
sum, cnt, a, pow : array[0..2000000] of int64;
n, m, i, j, x, y : longint;
ch : char;
begin
readln(n, m);
pow[0] := 1;
for i := 1 to n + 1 do pow[i] := pow[i - 1] << 1;
for i := 1 to m do
begin
x := 0;
for j := 1 to n do
begin
read(Ch);
inc(x, (ord(ch) - 48) * pow[n - j]);
end;
readln(ch, y);
a[x] := (a[x] + y) mod p;
end;
cnt[0] := 1; sum[0] := a[0];
for i := 1 to pow[n] - 1 do
begin
j := i;
while true do
begin
j := (j - 1) and i;
cnt[i] := (cnt[i] + cnt[j]) mod p;
sum[i] := (sum[i] + sum[j]) mod p;
if j = 0 then break;
end;
sum[i] := (sum[i] + cnt[i] * a[i]) mod p;
end;
writeln(sum[pow[n] - 1]);
end.
100分
对于题目输入的
s
t
a
t
e
i
statei
statei,我们把它看成中间状态,即从0变到这个状态,在从这个状态变到全部1的方案
那么乘法原理
令opt[i]为变i个1的方案数
每次加
o
p
t
[
c
n
t
]
∗
o
p
t
[
n
−
c
n
t
]
∗
a
opt[cnt] * opt[n - cnt] *a
opt[cnt]∗opt[n−cnt]∗a
而opt则如此算:
o
p
t
[
i
]
=
∑
j
=
1
i
o
p
t
[
i
−
j
]
∗
C
(
i
,
j
)
opt[i] = \sum_{j=1}^{i} opt[i-j]*C(i,j)
opt[i]=∑j=1iopt[i−j]∗C(i,j)
Code:
const
p = 998244353;
var
c : array[0..100, 0..100] of int64;
opt : array[0..10000] of int64;
ch : char;
n, m, i, j, cnt, x : longint;
ans : int64;
begin
readln(n, m);
for i := 0 to n do c[i][0] := 1;
for i := 1 to n do
for j := 1 to n do
c[i][j] := (c[i - 1][j] + c[i - 1][j - 1]) mod p;
opt[0] := 1;
for i := 1 to n do
for j := 1 to i do
opt[i] := (opt[i] + opt[i - j] * c[i][j]) mod p;
for i := 1 to m do
begin
cnt := 0;
for j := 1 to n do
begin
read(ch);
inc(cnt, ord(ch) - 48);
end;
readln(ch, x);
ans := (ans + opt[cnt] * x mod p * opt[n - cnt] mod p) mod p;
end;
writeln(ans);
end.
总得分:243
炸了,真的炸了,所以我得到一个结论:珍爱生命,远离slay
当然,学的累了,颓一会儿也是可以的~~