The 2019 China Collegiate Programming Contest Harbin Site

題目鏈接:https://codeforces.com/gym/102394

 

A - Artful Paintings

設S[i]表示前i個位置放了i個燈泡,那麼就有這麼一些關係,0 <= S[i] - S[i-1] <= 1,S[Ri] - S[Li-1] >= Ki,S[n] - (S[Ri] - S[Li-1]) >= Ki

由於第三個式子有三個未知數,又S[n]具有單調性質,所以二分S[n]使得第三個式子變成兩個而知數,同時又有

x<=S[n]<=x,將這些關係利用差分約束建立圖,然後跑最短路看是否有解

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef pair <int,int> pa;
const int mx = 6e3 + 10;
int n,m1,m2;
int dis[mx];
int cnt[mx];
vector <pa> g[mx];
bool vis[mx];
struct node {
	int l,r;
	int k;
}s[mx];
bool spfa (int mid) {
	memset(dis,inf,sizeof(int)*(n+2));
	memset(cnt,0,sizeof(int)*(n+2));
	memset(vis,0,n+2);
	dis[0] = 0, cnt[0]++;
	queue <int> q;
	q.push(0);
	int limit = n;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		vis[u] = 0;
		for (pa now:g[u]) {
			int v = now.first;
			int w = now.second;
			if (dis[v] > dis[u] + w) {
				dis[v] = dis[u] + w;
				if (dis[v] < 0) return 0;
				if (!vis[v]) {
					vis[v] = 1;
					if (++cnt[v] > limit) return 0;
					q.push(v);
				}
			} 
		}
	}
	return 1;
}
bool check(int mid) {
	for (int i=0;i<=n;i++)
		g[i].clear();
	for (int i=0;i<n;i++)
		g[i].push_back(pa(i+1,1));
	for (int i=1;i<=n;i++)
		g[i].push_back(pa(i-1,0));
	for (int i=1;i<=m1;i++) 
		g[s[i].r].push_back(pa(s[i].l-1,-s[i].k));
	for (int i=m1+1;i<=m1+m2;i++) 
		g[s[i].l-1].push_back(pa(s[i].r,mid-s[i].k));
	g[0].push_back(pa(n,mid));
	g[n].push_back(pa(0,-mid));
	return spfa(mid);
}
int main() {	
	int t;
	scanf("%d",&t);
	while (t--) {
		scanf("%d%d%d",&n,&m1,&m2);
		for (int i=1;i<=m1+m2;i++) {
			scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].k);
		}	
		int l = 0, r = n;
		while (l < r) {
			int mid = l + r >> 1;
			if (check(mid))
				r = mid;
			else
				l = mid + 1;
		}
		printf("%d\n",l);
	}
	return 0;
}

B - Binary Numbers

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair <int,int> pa;
typedef long long ll;
const int mx = 1<<18;
const int mod = 1e8 + 7;
int n,m; 
ll bit_val;
int dp[mx][20][20];
pa sp[mx];
void global_init() {
	for (int i=1;i<=n;i++) {
		for (int j=0;j<=m;j++){
			for (int k=0;k<=m;k++)
				dp[i][j][k] = 0;
		}
	}
}
int get_lcp(int u,int v) {
	for (int i=m-1;i>=0;i--) {
		bool val1 = u&(1<<i);
		bool val2 = v&(1<<i);
		if (val1^val2) return m - (i+1); 
	}
	return m;
} 
int main() {
	int t;scanf("%d",&t);
	while (t--) {
		scanf("%d%d",&m,&n);
		global_init();
		int u,v;
		for (int i=1;i<=n;i++) {
			scanf("%d%d",&u,&v);
			sp[i] = pa(u,v);
		}
		for (int i=0;i<=sp[1].se;i++) {
			u = get_lcp(i,sp[1].se+1);
			v = get_lcp(i,sp[1].se);
			dp[1][u][v] = (dp[1][u][v] + i) % mod;;
		}
		for (int i=2;i<=n;i++) {
			for (int j=sp[i].fi;j<=sp[i].se;j++) {
				int lv = get_lcp(j,sp[i].fi);
				int rv = get_lcp(j,sp[i].fi-1);
				int nlv = get_lcp(j,sp[i].se+1);
				int nrv = get_lcp(j,sp[i].se);
				for (int k=0;k<=lv;k++) {
					for (int q=rv;q<=m;q++) if(dp[i-1][k][q]){
						dp[i][nlv][nrv] += 1ll*j*dp[i-1][k][q]%mod;
						dp[i][nlv][nrv] %= mod;
					}
				}
			}
		}
		ll ans = 0;
		for (int i=0;i<=m;i++) {
			for (int j=0;j<=m;j++)
				ans = (ans + dp[n][i][j])%mod; 
		}
		printf("%lld\n",ans);
	}   
    return 0;
}

I - Interesting Permutation

#include <bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair <int,int> pa;
typedef long long ll;
const int mx = 1e5 + 10;
const int mod = 1e9 + 7;
int n,m; 
int a[mx];
int main() {  
	int t;scanf("%d",&t);
	while (t--) {
		scanf("%d",&n);
		for (int i=1;i<=n;i++) {
			scanf("%d",a+i);
		}
		ll ans = 1;
		int cnt = 0;
		if (a[1] != 0 || a[n] != n-1) ans = 0;
		for (int i=2;i<=n;i++) {
			if (a[i]<a[i-1]) ans = 0;
			if (a[i]==a[i-1]) {
				ans = ans*(cnt--)%mod;
			} else {
				ans = ans*2%mod;
				cnt += a[i] - a[i-1] - 1;
			}
		}
		printf("%lld\n",ans);
	}
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章