ACM-ICPC 2018 南京赛区网络预赛

A. An Olympian Math Problem

题意

$S=1×1!+2×2!+⋯+(n - 1) \times (n-1)!(n−1)×(n−1)!$问$Smodn$是多少。

题解

思维题,打表题?答案就是$n-1$证明如下。

看到$n-1$很不爽,那就加一个$(n-1)!$就凑好了。

$S+1!+2!+…+(n-1)!=2!+3!+…+n!$

之后再减掉。

$S=n!-1!$那么对$n$取余$S modn=-1modn=n-1$搞定。

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include
using
#define
#define
#define
#define
typedef
typedef
const
//head
int
ll n;
int
#ifdef
freopen("1.in"
#endif
scanf
while
scanf
printf
}
return
}

B. The writing on the wall

E. AC Challenge

题意

做题目,要按照一定顺序做题目,每个题目有两个值$a,b$,表示做了题目后增加$t*a+b$。

题解

状态压缩+剪枝+拓扑排序。

因为$n$的数据量小于$20$所以可以使用状态压缩。

$S$表示已经做的题目。

$vs$数组存储已知做题的最大值。如果做同样的题值比较小就减掉。

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include
using
#define
#define
#define
#define
typedef
typedef
const
//head
const
struct
int
}G[maxn*maxn*3
int
ll a[maxn],b[maxn];
int
void
G[cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt++;
}
int
ll ans = 0
ll vis[maxn];
ll vs[1
void
ans = max(ans,temp);
if
vs[S] = temp;
for
int
ind[v]--;
}
rep(i,1
if
vis[i] = 1
dfs(i,t+1
vis[i] = 0
}
}
for
int
ind[v]++;
}
}
int
#ifdef
freopen("e.in"
#endif
memset
scanf
rep(i,1
int
rep(j,0
int
add(u,i);ind[i]++;
}
}
rep(i,1
if
ind[i]++;
add(0
}
}
ans = 0
dfs(0
printf
return
}

G. Lpl and Energy-saving Lamps

题意

一个人去给所有房间换灯泡,每个月都会获得$m$个灯泡,每个房间有$a_i$个灯泡,之后以能换就换的态度每个月从第一个房间开始换,没有能换的房间就停止,把灯泡留到下一个月。换过灯泡就不用再换了。问给定月份中已经换好的房间数和当月剩下的灯泡数。

题解

线段树维护一个区间最小值。

由于线段树遍历是从前往后的,就不用担心顺序问题。

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include
using
#define
#define
#define
#define
#define
#define
typedef
typedef
const
//head
const
int
int
int
void
Min[rt] = min(Min[rt
- 马拉车+hash

- 回文树+dfs

### AC代码1

```cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include
#include
#include
#include
#include
#include
#include
using
#define
#define
const
const
ULL P = 1313131
ULL sqr[maxn/2
ll ha[maxn/2
int

const

bool
{
int
for
if
}
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
V[cnt]=Now;
return
}
ll ans=0
void
ULL Now=has[y]-has[x-1
if
{
ans+=((ha[y]-ha[x-1
ans%=mod;
}
}
int
char
void
{
int

scanf
Len=strlen
sqr[0
has[0
for
sqr[i]=sqr[i-1
has[i]=has[i-1
tmp[i]=tmp[i-1
ha[i]=(ha[i-1
}

for
_hash(i,i);
if
while
_hash(i-r[i]-1
r[i]++;
}
if
R=i+r[i];
Mid=i;
}
}

cnt=0
memset
memset
for
if
while
_hash(i-r[i]-1
++r[i];
}
if
R=i+r[i]-1
Mid=i;
}
}
printf
}
int

_malacher();
return
}

AC代码2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include
#include
using
typedef
const
const

ll pow
ll t,y;
t=1
while
if
y=y*y%MOD; b=b>>1
}
return
}

int
int
int
int
int
int
int
int
int

int
cnt[tot]=0
num[tot]=0
len[tot]=l;
return
}

void
tot=0
new_node(0
new_node(-1
last=0
N=0
S[N]=-1
fail[0
}

int
while
x=fail[x];
return
}

void
c-='0'
S[++N]=c;
int
if
int
fail[now]=nxt[get_fail(fail[cur])][c];
nxt[cur][c]=now;
num[now]=num[fail[now]]+1
}
last=nxt[cur][c];
cnt[last]++;
}

ll jans=0
ll oans=0

void
for
if
ll cur;
if
jans+=i;
cur=i;
jans%=MOD;
}
else
cur=i*pow
jans=(jans+cur%MOD)%MOD;
jans%=MOD;
}
dfs1(nxt[x][i],cur%MOD);
}
}
}

void

for
if
ll cur;
cur=i*pow
oans=(oans+cur%MOD)%MOD;
dfs2(nxt[x][i],cur%MOD);
}
}
}

char

int
scanf
int
init_tree();
for
add_char(str[i]);
dfs1(1
dfs2(0
printf
return
}

L. Magical Girl Haze

题意

给定一个图,问从$1$走到$n$如果可以选择$k$条路为$0$,那么最短的路径是多少。

题解

分层图最短路+堆优化dijistra

每使用一次道路为0,就进入$step+1$的路径比较。比较好的dp思维。对于pair使用了一个小trick,负值就可以不用手写greater和重载小于了。但是现场赛应该还是手写node算了。

dp转移两种状态.

  • $dp[v][step+1] = min(dp[v][step+1],dp[u][step])$

  • $dp[v][step] = min(dp[v][step],dp[u][step]+val(u,v))$

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include
using
#define
#define
#define
#define
#define
typedef
typedef
const
//head
const
int
struct
int
}G[maxn
2018 ICPC南京赛区网络赛

https://www.cheasim.com/acm/2018/09/03/2018-ICPC%E5%8D%97%E4%BA%AC%E8%B5%9B%E5%8C%BA%E7%BD%91%E7%BB%9C%E8%B5%9B.html

作者
CheaSim

发布于
2018-09-03

更新于
2018-09-04

许可协议

#[网络赛](/tags/%E7%BD%91%E7%BB%9C%E8%B5%9B/)