Hello 2020 题解

New Year and Naming

[Time Limit: 1 squad Memory Limit: 256 MB ]

取模计算即可。

view
/*************************************************************** 
    > File Name        : a.cpp
    > Author           : Jiaaaaaaaqi
    > Created Time     : 2020/1/4 19:57:41
 ***************************************************************/

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

char s[50][50], t[50][50];

int main() {
	// freopen("in", "r", stdin);
	scanf("%d%d", &n, &m);
	for(int i=1; i<=n; i++)	scanf("%s", s[i]+1);
	for(int i=1; i<=m; i++)	scanf("%s", t[i]+1);
	scanf("%d", &T);
	while(T--) {
		ll x;
		scanf("%lld", &x);
		ll a = x%n, b = x%m;
		if(a==0)	a = n;
		if(b==0)	b = m;
		printf("%s%s
", s[a]+1, t[b]+1);
	}
	return 0;
}

New Year and Ascent Sequence

[Time Limit: 2 squad Memory Limit: 256 MB ]

对于每一个数列,先判断其本身是否可以拿出两个递增的数。如果可以的话,其可以和任意其他数列组成一个合法答案。如果不可以的话,可以尝试把其放在前面,选出他的最小值,然后找出有多少个数列可以放在后面,并且选出数列的最大值大于此数列的最小值,这一段可以通过二分得到。

剩下的只要扣除重复计算的部分即可。

view
/*************************************************************** 
    > File Name        : b.cpp
    > Author           : Jiaaaaaaaqi
    > Created Time     : 2020/1/4 20:19:01
 ***************************************************************/

#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>

typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;

int n, m;
int cas, tol, T;

bool vis[maxn];
int a[maxn], b[maxn], c[maxn];
vector<int> g;

int main() {
	// freopen("in", "r", stdin);
	ll ans = 0;
	scanf("%d", &n);
	g.clear();
	int cnt = 0;
	for(int i=1; i<=n; i++) {
		scanf("%d", &m);
		a[i] = inf, b[i] = 0;
		for(int j=1; j<=m; j++) {
			scanf("%d", &c[j]);
			a[i] = min(a[i], c[j]);
			b[i] = max(b[i], c[j]);
		}
		vis[i] = 0;
		int Min = c[1];
		for(int j=2; j<=m; j++) {
			if(Min < c[j]) {
				vis[i] = 1;
				break;
			}
			Min = min(Min, c[j]);
		}
		if(!vis[i])	g.pb(b[i]);
		if(vis[i])	ans += n+n-1, cnt++;
	}
	ans -= 1ll*(cnt)*(cnt-1);
	sort(g.begin(), g.end());
	g.pb(inf);
	for(int i=1; i<=n; i++) {
		if(vis[i])	continue;
		int p = upper_bound(g.begin(), g.end(), a[i])-g.begin();
		ans += g.size()-p-1;
	}
	printf("%lld
", ans);
	return 0;
}

New Year and Permutation

[Time Limit: 1 squad Memory Limit: 256 MB ]

枚举区间长度,然后计算可以拿多少个连续的区间放在多少段连续的位置,然后分成选出的数和没选出的数全排列放即可。

view
/*************************************************************** 
    > File Name        : c.cpp
    > Author           : Jiaaaaaaaqi
    > Created Time     : 2020/1/4 21:03:22
 ***************************************************************/
 
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
 
typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 1e6 + 10;
const int    maxm = 1e5 + 10;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;
 
ll n, m, mod;
int cas, tol, T;
 
ll A[maxn];
 
int main() {
	// freopen("in", "r", stdin);
	scanf("%lld%lld", &n, &mod);
	A[0] = 1%mod;
	for(int i=1; i<=n; i++)	A[i] = A[i-1]*i%mod;
	ll ans = 0;
	for(int i=1; i<=n; i++) {
		ans += A[i]*A[n-i]%mod*(n-i+1)%mod*(n-i+1)%mod;
		ans %= mod;
	}
	printf("%lld
", ans);
	return 0;
}

New Year and Conference

[Time Limit: 2 squad Memory Limit: 256 MB ]

对于每个时间点 (t),我们可以维护有哪些会议 (t) 时刻正在 (A) 场地进行,假设有 (cnt) 个会议,那么这 (cnt) 个会议都是两两冲突的,那么这 (cnt) 个会议在 (B) 场地也必须是两两冲突的,也就是说必须有一个时刻被这些会议的 ([sb, eb]) 区间覆盖。

那么可以在 (sa) 时刻加入 ([sb, eb]) 区间,在 (ea+1) 时刻删除 ([sb, eb]) 区间,那么可以用线段树来维护每一时刻在 (B) 场地被多少个会议覆盖,然后就可以通过线段树的最大值来判断是否合法。

此时判断的是 (A) 场地冲突时,(B) 场地是不是都冲突。只需要再反过来判断 (B) 场地冲突时,(A) 场地是不是都冲突即可。

view
/*************************************************************** 
    > File Name        : d.cpp
    > Author           : Jiaaaaaaaqi
    > Created Time     : 2020/1/6 21:03:02
 ***************************************************************/
 
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <cfloat>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#define  lowbit(x)  x & (-x)
#define  mes(a, b)  memset(a, b, sizeof a)
#define  fi         first
#define  se         second
#define  pb         push_back
#define  pii        pair<int, int>
 
typedef unsigned long long int ull;
typedef long long int ll;
const int    maxn = 4e5 + 10;
const int    maxm = 1e5 + 10;
const ll     mod  = 1e9 + 7;
const ll     INF  = 1e18 + 100;
const int    inf  = 0x3f3f3f3f;
const double pi   = acos(-1.0);
const double eps  = 1e-8;
using namespace std;
 
int n, m;
int cas, tol, T;
 
vector<int> vv;
vector<pii> g[maxn];
int sa[maxn], ea[maxn], sb[maxn], eb[maxn];
int node[maxn<<2], lazy[maxn<<2];
 
int getid(int x) {
	return lower_bound(vv.begin(), vv.end(), x) - vv.begin()+1;
}
 
void build(int l, int r, int rt) {
	node[rt] = lazy[rt] = 0;
	if(l==r)	return ;
	int mid = l+r>>1;
	build(l, mid, rt<<1);
	build(mid+1, r, rt<<1|1);
}
 
void pushdown(int rt) {
	if(lazy[rt]) {
		lazy[rt<<1] += lazy[rt];
		lazy[rt<<1|1] += lazy[rt];
		node[rt<<1] += lazy[rt];
		node[rt<<1|1] += lazy[rt];
		lazy[rt] = 0;
	}
}
 
void update(int l, int r, int pl, int pr, int val, int rt) {
	if(pl<=l && r<=pr) {
		node[rt] += val, lazy[rt] += val;
		return ;
	}
	int mid = l+r>>1;
	pushdown(rt);
	if(pl<=mid)	update(l, mid, pl, pr, val, rt<<1);
	if(pr>mid)	update(mid+1, r, pl, pr, val, rt<<1|1);
	node[rt] = max(node[rt<<1], node[rt<<1|1]);
}
 
bool ok() {
	int cnt = 0;
	build(1, tol, 1);
	for(int i=1; i<=tol; i++) {
		for(auto t : g[i])	update(1, tol, sb[t.se], eb[t.se], t.fi, 1), cnt += t.fi;
		if(node[1] != cnt)	return false;
	}
	return true;
}
 
int main() {
	// freopen("in", "r", stdin);
	scanf("%d", &n);
	for(int i=1; i<=n; i++) {
		scanf("%d%d%d%d", &sa[i], &ea[i], &sb[i], &eb[i]);
		vv.pb(sa[i]), vv.pb(ea[i]), vv.pb(sb[i]), vv.pb(eb[i]);
	}
	sort(vv.begin(), vv.end()), vv.erase(unique(vv.begin(), vv.end()), vv.end());
	for(int i=1; i<=n; i++) {
		sa[i] = getid(sa[i]), ea[i] = getid(ea[i]);
		sb[i] = getid(sb[i]), eb[i] = getid(eb[i]);
		g[sa[i]].pb({1, i});
		g[ea[i]+1].pb({-1, i});
	}
	tol = vv.size();
	if(!ok())	return 0*puts("NO");
	for(int i=1; i<=tol+1; i++)	g[i].clear();
	for(int i=1; i<=n; i++) {
		swap(sa[i], sb[i]), swap(ea[i], eb[i]);
		g[sa[i]].pb({1, i});
		g[ea[i]+1].pb({-1, i});
	}
	if(!ok())	return 0*puts("NO");
	return 0*puts("YES");
}
原文地址:https://www.cnblogs.com/Jiaaaaaaaqi/p/12158877.html