洛谷7月月赛

【LGR-049】洛谷7月月赛

比赛开始一个小时才想起来QwQ,当场写了ABC

#A: P4752 Divided Prime

日常送分题 注意只留一个非1数判他是不是质数

#B: P4753 River Jumping

题意:有跳跃距离下限,求能否经过所有石头恰好一次跳一个来回

贪心

首先距离河岸最近的两个石头必须要能跳上,剩下最多的隔一个跳一个(因为是来回)

#C: P4754 True Vegetable

经典的二分+贪心

二分最小回合数,把所有菜气都减去,然后从左到右贪心加,bit维护

一开始以为r值没用,原来r值保证了答案的单调性

#D: P4755 Beautiful Pair

题意:小D有个数列 \({a}\) ,当一个数对 \((i,j)(i≤j)\) 满足 \(a_i*a_j \le \max(a_i,a_{i+1},…,a_j)\) ,小D认为这个数对是美丽的.请你求出美丽的数对的数量。

单调栈处理出每个值作为最大值的长度a_x [l,r]

然后对于[l,x]中每个值\(a_i\),找[x,r]中满足\(a_j \le \frac{a_x}{a_i}\)的数量,这里可以用主席树实现

但这样复杂度不对,可以选长度短的一段来枚举

复杂度 \(T(n) = T(a) + T(n-a-1) + O(n\log n) = O(n\log^2 n),其中a \le n/2\)

问了一下,可以数归证明。其实就是启发式合并

//D
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5+5;

int n, a[N], mp[N], m;
int st[N], top, l[N], r[N];
void init() {
	for(int i=1; i<=n; i++) {
		int le = i;
		while(top && a[st[top]] <= a[i]) {
			le = l[st[top]];
			r[st[top]] = i-1;
			top--;
		}
		st[++top] = i;
		l[i] = le;
	}
	while(top) r[st[top--]] = n;

	sort(mp+1, mp+1+n);
	m = unique(mp+1, mp+1+n) - mp - 1;
}


struct node {
	int lc, rc, size;
} t[N*18];
int sz, root[N];
void ins(int &x, int l, int r, int p) {
	t[++sz] = t[x]; x = sz;
	t[x].size ++;
	if(l == r) return;
	int mid = (l+r) >> 1;
	if(p <= mid) ins(t[x].lc, l, mid, p);
	else ins(t[x].rc, mid+1, r, p);
}
int que(int x, int y, int l, int r, int ql, int qr) {
	if(mp[r] < ql || qr < mp[l]) return 0;
	if(ql <= mp[l] && mp[r] <= qr) return t[y].size - t[x].size;
	int mid = (l+r) >> 1, ans = 0;
	if(ql <= mp[mid]) ans += que(t[x].lc, t[y].lc, l, mid, ql, qr);
	if(mp[mid] < qr) ans += que(t[x].rc, t[y].rc, mid+1, r, ql, qr);
	return ans;
}

long long ans;
void solve(int l1, int r1, int l2, int r2, int mid) { 
	for(int i=l1; i<=r1; i++) {
		int v = a[mid] / a[i];
		ans += que(root[l2-1], root[r2], 1, m, 1, v);
	}
}
int main() {
	freopen("in", "r", stdin);
	ios::sync_with_stdio(false); cin.tie(); cout.tie();
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i], mp[i] = a[i];
	init();
	//for(int i=1; i<=n; i++) printf("hi %d [%d %d]\n", i, l[i], r[i]);
	for(int i=1; i<=n; i++) {
		int x = lower_bound(mp+1, mp+1+m, a[i]) - mp;
		root[i] = root[i-1];
		ins(root[i], 1, m, x);
	}
	for(int i=1; i<=n; i++) {
		int le = l[i], ri = r[i];
		int d1 = i-le, d2 = ri-i;
		//if(d1 == 0 || d2 == 0) continue;

		if(d1 <= d2) solve(le, i, i, ri, i);
		else solve(i, ri, le, i, i);
	}
	cout << ans;
}
//A
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
typedef long long ll;
using namespace std;
const int N = 1e5+5;

int n, m, c[N];
ll a[N], b[N], mp[N];

bool is_p(ll n) {
	for(ll i=2; i*i<=n; i++) if(n%i == 0) return false;
	return true;
}
int main() {
	freopen("in", "r", stdin);
	ios::sync_with_stdio(false);
	int T;
	cin >> T;
	while(T--) {
		mp[0] = 0;
		memset(c, 0, sizeof(c));
		cin >> n >> m;
		for(int i=1; i<=n; i++) cin >> a[i], mp[i] = a[i];
		sort(mp+1, mp+1+n);
		mp[0] = unique(mp+1, mp+1+n) -mp -1;

		for(int i=1; i<=n; i++) {
			int x = lower_bound(mp+1, mp+1+mp[0], a[i]) - mp;
			c[x]++;
		}
		for(int i=1; i<=m; i++) {
			cin >> b[i];
			int x = lower_bound(mp+1, mp+1+mp[0], b[i]) - mp;
			c[x]--;
		}

		int cnt = 0;
		ll ans = 0;
		for(int i=1; i<=mp[0]; i++) if(mp[i] != 1 && c[i]) {
			cnt+=c[i];
			ans = mp[i];
		}
		if(cnt!=1) puts("NO");
		else if(!is_p(ans)) puts("NO");
		else puts("YES");
	}
}
//B
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
typedef long long ll;
using namespace std;
const int N = 1e5+5;


int n, m, s, x[N], vis[N];
vector<int> v;
bool solve() {
	int now = 0;
	if(x[1] < s) return false;
	now = 1; vis[1] = 1; v.push_back(1);
	while(now+2 <= m) {
		if(x[now+2] - x[now] < s) return false;
		vis[now+2] = 1; v.push_back(now+2);
		now += 2;
	}
	if(now == m-1) {
		if(x[m] - x[now] < s) return false;
		vis[m] = 1; v.push_back(m);
		now ++;
	}
	for(int i=m-1; i>=0; i--) if(!vis[i]) {
		if(x[now] - x[i] < s) return false; 
		now = i; v.push_back(i);
	}
	return true;
}
int main() {
	freopen("in", "r", stdin);
	ios::sync_with_stdio(false);

	cin >> n >> m >> s;
	for(int i=1; i<=m; i++) cin >> x[i];
	x[0] = 0; x[++m] = n;
	
	if(!solve()) cout << "NO" << endl;
	else {
		cout << "YES" << endl;
		for(int i=0; i<v.size(); i++) cout << v[i] << " ";
	}
}

//C
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
typedef long long ll;
using namespace std;
const int N = 6e5+5;

int n, m, k, L, a[N], A[N], r[105], w[N], x[N], v[N];

int c[N];
inline void add(int p, int v) { //printf("add %d %d\n", p, v); cout << endl;
	for(; p<=n; p+=p&-p) c[p] += v;
}
inline int sum(int p) {
	int ans = 0;
	for(; p; p-=p&-p) ans += c[p];
	return ans;
}
inline void add(int l, int r, int v) {
	add(l, v);
	add(r+1, -v);
}

bool check(int mid) { //printf("check %d\n", mid);
	for(int i=1; i<=n; i++) a[i] = A[i];
	for(int p = 1; p <= m && w[p] <= mid; p++) a[x[p]] -= v[p];

	memset(c, 0, sizeof(c));
	for(int i=n; i>=1; i--) a[i] -= a[i-1];
	for(int i=1; i<=n; i++) add(i, a[i]);
	

	int ans = 0;
	for(int i=1; i<=n; i++) {
		int x = sum(i); //printf("hi %d %d\n", i, x);
		if(x < 1) add(i, i+k-1, 1-x), ans += 1-x; 
	} 
	//printf("ans %d\n", ans);
	return ans <= mid;
}
int main() {
	freopen("in", "r", stdin);
	ios::sync_with_stdio(false);

	cin >> n >> m >> k >> L;
	for(int i=1; i<=n; i++) cin >> A[i];
	for(int i=1; i<=L; i++) cin >> r[i];
	for(int i=1; i<=m; i++) cin >> w[i] >> x[i] >> v[i];
	int l = 0, r = 1e8, ans = 0;
	while(l <= r) { //printf("erfen %d %d\n", l, r);
		int mid = (l+r) >> 1;
		if(check(mid)) ans = mid, r = mid-1;
		else l = mid+1;
	}
	cout << ans;
}
posted @ 2018-07-16 11:17  Candy?  阅读(...)  评论(...编辑  收藏