【比赛】8.13

发布时间 2023-08-13 14:37:20作者: jiangchenyangsong

Ⅰ.波状数列

考试时想到的是用 \(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;
}