Ⅰ.波状数列
考试时想到的是用 \(f_{i,0/1}\) 表示用了 前 \(i\) 个数,其中第一个数是山峰还是山谷。比较麻烦。
之前看题解做的时候,用 \(f_{i,j}\) 表示用了前 \(i\) 个数,其中第一个数是 \(j\),滚动数组优化一下。
点击查看代码
#include<bits/stdc++.h>
#define int long long
const int N = 1e3 + 67;
using namespace std;
int read(){
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){f = -f; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return x * f;
}
int n, mod;
int f[N][2], C[N][N];
signed main(){
//freopen("irrev.in", "r", stdin);
//freopen("irrev.out", "w", stdout);
n = read(), mod = read();
// if(n == 1) return printf("%lld\n", 1 % mod), 0;
// if(n == 2) return printf("%lld\n", 2 % mod), 0;
f[1][0] = 1, f[1][1] = 1;
f[2][0] = 1, f[2][1] = 1;
C[0][0] = 1;
for(int i = 1; i <= n; ++i){
C[i][i] = 1, C[i][0] = 1;
for(int j = 1; j < i; ++j) C[i][j] = C[i - 1][j] + C[i - 1][j - 1], C[i][j] %= mod;
}
for(int i = 3; i <= n; ++i){
f[i][1] = f[i - 1][0];
if((i - 1) & 1) f[i][0] = f[i - 1][0];
else f[i][1] += f[i - 1][1];
for(int j = 2; j < i; ++j){
if((j - 1) & 1) f[i][0] += f[j - 1][0] * f[i - j][0] % mod * C[i - 1][j - 1] % mod, f[i][0] %= mod;
else f[i][1] += f[j - 1][1] * f[i - j][0] % mod * C[i - 1][j - 1] % mod, f[i][1] %= mod;
}
}
printf("%lld\n", (f[n][0] + f[n][1]) % mod);
return 0;
}
Ⅱ. Steady Cow Assignment
看到 B 的范围很小,显然可以枚举范围,再用网络流判断是否有解。见图的时候,如果每次都重建显然复杂度过高,所以我们可以从前往后依次加边来减小时间复杂度。
网络流边数一定要开大一点。
点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 2e4 + 67, M = 6e5 + 67;
using namespace std;
int read(){
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){f = -f; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return x * f;
}
int n, B, s, t, tot = 1, ans = 25;
int Head[N], to[M << 1], Next[M << 1], edge[M << 1];
void add(int u, int v, int w){
to[++tot] = v, Next[tot] = Head[u], Head[u] = tot, edge[tot] = w;
to[++tot] = u, Next[tot] = Head[v], Head[v] = tot, edge[tot] = 0;
}
int a[N][25], b[25];
int d[N], now[N];
bool bfs(){
memset(d, 0, sizeof(d));
queue<int> q;
q.push(s); now[s] = Head[s]; d[s] = 1;
while(!q.empty()){
int x = q.front(); q.pop();
for(int i = Head[x]; i; i = Next[i]){
int y = to[i]; if(!edge[i] || d[y]) continue;
now[y] = Head[y], d[y] = d[x] + 1; q.push(y);
if(y == t) return true;
}
}
return false;
}
int dinic(int x, int flow){
if(x == t) return flow;
int rest = flow;
for(int i = now[x]; i && rest; i = Next[i]){
int y = to[i]; now[x] = i;
if(!edge[i] || d[y] != d[x] + 1) continue;
int k = dinic(y, min(rest, edge[i]));
if(!k) d[y] = 0;
edge[i] -= k, edge[i ^ 1] += k, rest -= k;
}
return flow - rest;
}
signed main(){
// freopen("stead.in", "r", stdin);
// freopen("stead.out", "w", stdout);
n = read(), B = read(), s = n + B + 1, t = n + B + 2;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= B; ++j)
a[i][j] = read();
for(int i = 1; i <= B; ++i) b[i] = read();
for(int o = 1; o <= B; ++o){
memset(Head, 0, sizeof(Head));
for(int i = 1; i <= n; ++i) add(s, i, 1);
for(int i = 1; i <= B; ++i) add(n + i, t, b[i]);
int flow = 0, maxflow = 0;
for(int j = o; j <= B; ++j){
for(int i = 1; i <= n; ++i) add(i, a[i][j] + n, 1);
while(bfs())
while(flow = dinic(s, INF)) maxflow += flow;
if(maxflow == n){
ans = min(ans, j - o + 1);
break;
}
}
}
printf("%d\n", ans);
return 0;
}
Ⅲ.导航软件
分层图模板
点击查看代码
#include<bits/stdc++.h>
#define ll long long
const int N = 5e5 + 67, M = 5e6 + 67;
using namespace std;
int read(){
int x = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){f = -f; ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}
return x * f;
}
int n, m, k, tot;
int Head[N], Next[M << 1], edge[M << 1], to[M << 1];
ll dis[N];
bool vis[N];
void add(int u, int v, int w){
to[++tot] = v, Next[tot] = Head[u], Head[u] = tot, edge[tot] = w;
}
priority_queue<pair<int, int> > pq;
void dijkstra(int s){
pq.push(make_pair(0, s));
dis[s] = 0;
while(!pq.empty()){
int x = pq.top().second; pq.pop();
if(vis[x]) continue; vis[x] = 1;
for(int i = Head[x]; i; i = Next[i]){
int y = to[i];
if(dis[y] > dis[x] + edge[i]){
dis[y] = dis[x] + edge[i];
pq.push(make_pair(-dis[y], y));
}
}
}
}
signed main(){
// freopen("navigation.in", "r", stdin);
// freopen("navigation.out", "w", stdout);
memset(dis, 0x3f, sizeof(dis));
n = read(), m = read(), k = read();
for(int i = 1; i <= m; ++i){
int u = read(), v = read(), w = read();
add(u, v, w), add(v, u, w);
for(int j = 1; j <= k + 1; ++j){
int u1 = u + (j - 1) * n, v1 = v + (j - 1) * n;
int u2 = u + j * n, v2 = v + j * n;
add(u1, v1, w), add(v1, u1, w);
add(u1, v2, 0), add(v1, u2, 0);
}
}
dijkstra(1);
ll ans = dis[n];
for(int i = 1; i <= k; ++i) ans = min(ans, dis[n + n * i]);
printf("%lld\n", ans);
return 0;
}
Ⅳ.LYK loves music
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+11;
int n,m,Q,cnt,lstans,rt[N];
struct Pos{int id,v;}a[N];
struct Seg{int l,r,t,v;}tr[N*50];
inline bool cmp(Pos x,Pos y){return x.v<y.v;}
#define ls tr[q].l
#define rs tr[q].r
#define Ls tr[p].l
#define Rs tr[p].r
void give(int q,int p){ls=Ls;rs=Rs;tr[q].t=tr[p].t;tr[q].v=tr[p].v;}
void update(int q){tr[q].v=tr[q].t+min(tr[ls].v,tr[rs].v);}
void ins(int &q,int p,int l,int r,int L,int R,int v){
if(r<L||l>R) return ;
q=++cnt;give(q,p);
int mid=l+r>>1;
if(l>=L&&r<=R) tr[q].t+=v;
else ins(ls,Ls,l,mid,L,R,v),ins(rs,Rs,mid+1,r,L,R,v);
update(q);
}
int query(int q,int l,int r,int L,int R){
if(l>=L&&r<=R) return tr[q].v;
int mid=l+r>>1,re=N;
if(mid>=L) re=min(re,query(ls,l,mid,L,R));
if(mid<R) re=min(re,query(rs,mid+1,r,L,R));
return tr[q].t+re;
}
int lower(int v){
int l=1,r=n,re=0;
while(l<=r){
int mid=l+r>>1;
if(a[mid].v<v) re=mid,l=mid+1;
else r=mid-1;
}return re;
}
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[a[i].id=i].v=read();
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
ins(rt[i],rt[i-1],1,n,max(a[i].id-m+1,1),a[i].id,1);
int Q=read();
for(int i=1;i<=Q;i++){
int l=read(),r=read(),v=read();
v=v^lstans;int p=lower(v);
lstans=query(rt[p],1,n,l,r);
printf("%d\n",lstans);
}
return 0;
}