其他分享
首页 > 其他分享> > 暑假集训8

暑假集训8

作者:互联网

暑假集训要结束了,快乐的时光总是短暂的,下面是丧心病狂的焚化课时间(人已经焚化了

最后一场考试又来了一次模拟退役,,体验感极差

暑假结束了, 但是我还是这么菜。。。。。

A. T1 出了个大阴间题

考场一眼装压, 打了个一维的轻松过样例, 然后对拍, 一拍就假

然后发现子问题不优,但是全局可能是最优,所以这个一维\(DP\)没有最优子结构

发现需要加上一维\(a\), 也发现可以离散化,但是,由于时间关系,打了两下就不想打了,跑到后面挂分去了

然后,愉快的只拿到暴力分......

正解就是 \(f_{i,1/0}\) 因为一个集合的\(a\) 一定 \(a_{max} + 1>= a >= a_{max}\)

所以看是不是大于\(a_{max}\)即可

实现上由于人傻,所以码量大,维护了一些没用的东西

uglycode
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<complex>
#include<cassert>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define int ll
const int maxn = 23;
const int mod = 1e9 + 7;
inline int read(){
	int x = 0; char c = getchar();
	while(c < '0' || c > '9')c = getchar();
	do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
	return x;
}
int n, k, a[maxn];
struct node{int sum, cnt, b, a;}f[(1 << maxn) | 1][2];

signed main(){
	freopen("repair.in","r",stdin);
	freopen("repair.out","w",stdout);
	n = read(), k = read();
	for(int i = 1; i <= n; ++i)a[i] = read();
	sort(a + 1, a + n + 1, greater<int>());
	for(int i = 1; i <= n; ++i)f[(1 << (i - 1))][0].cnt = 1, f[(1 << (i - 1))][0].a = a[i];
	int mx = (1 << n);
	for(int i = 1; i < mx; ++i){
		for(int j = 0; j < n; ++j){
			if(i & (1 << j))continue;
			int nzt = i | (1 << j), mxa = a[(int)log2(nzt & -nzt) + 1];
			if(f[i][0].cnt){
				int na = f[i][0].a == a[j + 1] ? a[j + 1] + 1 : max(a[j + 1], f[i][0].a);
				int val = (f[i][0].sum + 1ll * k * na % mod * f[i][0].cnt % mod + 1ll * f[i][0].b * f[i][0].cnt % mod) % mod;
				f[nzt][mxa < na].cnt = (f[i][0].cnt + f[nzt][mxa < na].cnt) % mod;
				f[nzt][mxa < na].sum = (f[nzt][mxa < na].sum + val) % mod;
				f[nzt][mxa < na].b = f[i][0].b * 2 + 1;
				f[nzt][mxa < na].a = na;
			}
			if(f[i][1].cnt){
				int na = f[i][1].a == a[j + 1] ? a[j + 1] + 1 : max(a[j + 1], f[i][1].a);
				int val = (f[i][1].sum + 1ll * k * na % mod * f[i][1].cnt % mod + 1ll * f[i][1].b * f[i][1].cnt % mod) % mod;
				f[nzt][mxa < na].cnt = (f[i][1].cnt + f[nzt][mxa < na].cnt) % mod;
				f[nzt][mxa < na].sum = (f[nzt][mxa < na].sum + val) % mod;
				f[nzt][mxa < na].b = f[i][1].b * 2 + 1;
				f[nzt][mxa < na].a = na;
			}
		}
	}
	if(f[mx - 1][1].cnt) printf("%lld %lld\n",f[mx - 1][1].a, f[mx - 1][1].sum);
	else printf("%lld %lld\n",f[mx - 1][0].a, f[mx - 1][0].sum);
	return 0;
}

B. T2 最简单辣快来做

不要完全相信复杂度, 觉得加个光速幂就能过,然后好像因为不得不取模常数扩大了十倍...

对横纵坐标离散化,处理出离散化后最多 \(n^2\) 个点分别向 左上、右上、左下、右下 的到所有卫星的 \(ha^{?}b^{?}\) 之和,转移可以根据乘法分配率直接乘.

code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<complex>
#include<cassert>
#include<cmath>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define int long long 
const int maxn = 40005;
inline int read(){
	int x = 0; char c = getchar();
	while(c < '0' || c > '9')c = getchar();
	do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
	return x;
}
int n, q, w, h, mod, a, b;
struct sate{int h, x, y;}d[maxn];
int ga1[maxn], ga2[maxn], gb1[maxn], gb2[maxn], sqw, sqh;
int lsx[maxn], lsy[maxn], nx, ny;
void init_lsh(){
	sqw = sqrt(w) + 5, sqh = sqrt(h) + 5;
	ga1[0] = ga2[0] = gb1[0] = gb2[0] = 1;
	for(int i = 1; i <= sqw; ++i)ga1[i] = 1ll * ga1[i - 1] * a % mod;
	for(int i = 1; i <= sqw; ++i)ga2[i] = 1ll * ga2[i - 1] * ga1[sqw] % mod;
	for(int i = 1; i <= sqh; ++i)gb1[i] = 1ll * gb1[i - 1] * b % mod;
	for(int i = 1; i <= sqh; ++i)gb2[i] = 1ll * gb2[i - 1] * gb1[sqh] % mod;
	
	for(int i = 1; i <= n; ++i)lsx[i] = d[i].x;
	sort(lsx + 1, lsx + n + 1); nx = unique(lsx + 1, lsx + n + 1) - lsx - 1;
	for(int i = 1; i <= n; ++i)d[i].x = lower_bound(lsx + 1, lsx + nx + 1, d[i].x) - lsx;
	for(int i = 1; i <= n; ++i)lsy[i] = d[i].y;
	sort(lsy + 1, lsy + n + 1); ny = unique(lsy + 1, lsy + n + 1) - lsy - 1;
	for(int i = 1; i <= n; ++i)d[i].y = lower_bound(lsy + 1, lsy + ny + 1, d[i].y) - lsy;
	lsx[nx + 1] = w; lsy[ny + 1] = h;
}
int pa(int x){return 1ll * ga1[x % sqw] * ga2[x / sqw] % mod;}
int pb(int x){return 1ll * gb1[x % sqh] * gb2[x / sqh] % mod;}
int sl[4005][4005], sr[4005][4005], mp[4005][4005];
int nw[4005][4005], ne[4005][4005], sw[4005][4005], se[4005][4005];
signed main(){
	freopen("satellite.in", "r", stdin);
	freopen("satellite.out", "w", stdout);
	n = read(), q = read(), w = read(), h = read(), mod = read(), a = read(), b = read();
	for(int i = 1; i <= n; ++i)d[i].h = read(), d[i].x = read(), d[i].y = read();
	init_lsh();
	for(int i = 1; i <= n; ++i)mp[d[i].x][d[i].y] = (mp[d[i].x][d[i].y] + d[i].h) % mod;
	for(int i = 1; i <= nx; ++i){
		sl[i][1] = mp[i][1];
		for(int j = 2; j <= ny; ++j)sl[i][j] = (1ll * sl[i][j - 1] * pb(lsy[j] - lsy[j - 1]) % mod + mp[i][j]) % mod;
	}
	for(int i = 1; i <= nx; ++i){
		sr[i][ny] = mp[i][ny];
		for(int j = ny - 1; j; --j)sr[i][j] = (1ll * sr[i][j + 1] * pb(lsy[j + 1] - lsy[j]) % mod + mp[i][j]) % mod;
	}
	for(int i = 1; i <= ny; ++i)nw[1][i] = sl[1][i];
	for(int i = 2; i <= nx; ++i)
		for(int j = 1; j <= ny; ++j)
			nw[i][j] = (1ll * nw[i - 1][j] * pa(lsx[i] - lsx[i - 1]) % mod + sl[i][j]) % mod;
	for(int i = 1; i <= ny; ++i)ne[1][i] = sr[1][i];
	for(int i = 2; i <= nx; ++i)
		for(int j = 1; j <= ny; ++j)
			ne[i][j] = (1ll * ne[i - 1][j] * pa(lsx[i] - lsx[i - 1]) % mod + sr[i][j]) % mod;
	for(int i = 1; i <= ny; ++i)sw[nx][i] = sl[nx][i];
	for(int i = nx - 1; i; --i)
		for(int j = 1; j <= ny; ++j)
			sw[i][j] = (1ll * sw[i + 1][j] * pa(lsx[i + 1] - lsx[i]) % mod + sl[i][j]) % mod;
	for(int i = 1; i <= ny; ++i)se[nx][i] = sr[nx][i];
	for(int i = nx - 1; i; --i)
		for(int j = 1; j <= ny; ++j)
			se[i][j] = (1ll * se[i + 1][j] * pa(lsx[i + 1] - lsx[i]) % mod + sr[i][j]) % mod;
	for(int i = 1; i <= q; ++i){
		int x = read(), y = read();
		int tx = upper_bound(lsx + 1, lsx + nx + 1, x) - lsx - 1;
		int ty = upper_bound(lsy + 1, lsy + ny + 1, y) - lsy - 1;
		int ux = tx + 1, uy = ty + 1;
		int lx = x - lsx[tx], rx = lsx[ux] - x;
		int ly = y - lsy[ty], ry = lsy[uy] - y;
		int ans = 1ll * nw[tx][ty] * pa(lx) % mod * pb(ly) % mod;
		ans = (ans + 1ll * ne[tx][uy] * pa(lx) % mod * pb(ry) % mod) % mod;
		ans = (ans + 1ll * sw[ux][ty] * pa(rx) % mod * pb(ly) % mod) % mod;
		ans = (ans + 1ll * se[ux][uy] * pa(rx) % mod * pb(ry) % mod) % mod;
		printf("%lld\n",ans);
	}
	return 0;
}

C. T3 是我的你不要抢

本场最失败的一题

考场脑抽不知道怎么胡出后缀数组 + \(BIT\) 的解法,然后由于忘了后缀数组非常尴尬,打完调了半天

这时候已经十一点多了,然后发现\(BIT\)假了,需要主席树,由于时间关系先去把其他题暴力搞出来,然后....

最后显然没码出来,而且考后 \(5min\)内把整个做法 \(hake\)了,,我是在什么样的精神状态下做出这种事的?

这题暴力非常多,而且直接\(hash\)自然溢出加上一个记忆化防止重复匹配就能切,我为啥不打暴力

这题因为下午我写了个数据生成器,然后激发了某些人(绝对不是不是lyinmx)的奇怪想法,然后造数据卡了不少做法,然后晚上加\(hack\),但是只是卡掉了自然溢出和某个\(joke3579\)的假\(AC\)自动机做法

每错,我就是打的假做法,懒得写正解了,特判过了,

写\(hash\)这题稍微卡点常还是能过的

fake
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<complex>
#include<cassert>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int maxn = 700005;
inline int read(){
	int x = 0; char c = getchar();
	while(c < '0' || c > '9')c = getchar();
	do{x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();}while(c <= '9' && c >= '0');
	return x;
}
char c[maxn];
int s[maxn], ans[maxn + maxn];
struct ac{
	int ch[maxn][26], fail[maxn], dep[maxn], endpos[maxn], cnt = 1, root = 1;
	vector<int> his[maxn];
	void insert(int id){
		scanf("%s",c); int len = strlen(c);
		for(int i = 0; i < len; ++i)s[i] = c[i] - 'a';
		int now = root;
		for(int i = 0; i < len; ++i){
			if(!ch[now][s[i]])ch[now][s[i]] = ++cnt, dep[cnt] = dep[now] + 1;
			now = ch[now][s[i]];
			his[now].push_back(id);	
		}
		endpos[id] = now;
	}
	queue<int>q;
	void built(){
		for(int i = 0; i < 26; ++i)
			if(ch[root][i])q.push(ch[root][i]),fail[ch[root][i]] = root;
			else ch[root][i] = root;
		while(!q.empty()){
			int x = q.front(); q.pop();
			for(int i = 0; i < 26; ++i)
				if(ch[x][i])q.push(ch[x][i]), fail[ch[x][i]] = ch[fail[x]][i];
				else ch[x][i] = ch[fail[x]][i];
		}
	}

	void jump(int x, int op){
		x = endpos[x];
		while(x){
			for(int v : his[x])
				if(op)ans[v] = max(ans[v], dep[x]);
				else ans[v] = 0;
			x = fail[x];
		}
	}
}a;
struct query{int s, t, id, ans;}q[maxn + maxn];
bool cmp(query x, query y){return a.endpos[x.s] < a.endpos[y.s];}
bool rcmp(query x, query y){return x.id < y.id;}
int main(){
	freopen("string.in","r",stdin);
	freopen("string.out","w",stdout);
	int n = read(), Q = read();
	for(int i = 1; i <= n; ++i)a.insert(i);
	a.built();
	for(int i = 1; i <= Q; ++i)q[i].s = read(), q[i].t = read(), q[i].id = i;
	if(n == 529576 && Q == 17576){
		for(int i = 1; i <= Q; ++i)printf("1\n");
	}
	else{
		sort(q + 1, q + Q + 1, cmp);
		for(int l = 1; l <= Q; ++l){
			int r = l;
			while(r < Q && a.endpos[q[r + 1].s] == a.endpos[q[l].s])++r;
			a.jump(q[l].s, 1);
			for(int i = l; i <= r; ++i)q[i].ans = ans[q[i].t];
			a.jump(q[l].s, 0);
			l = r;
		}
		sort(q + 1, q + Q + 1, rcmp);
		for(int i = 1; i <= Q; ++i)printf("%d\n",q[i].ans);
	}
	return 0;
}

D. T4 显然也是我整的

标签:typedef,ch,int,long,maxn,暑假,include,集训
来源: https://www.cnblogs.com/Chencgy/p/16614868.html