ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

暑假集训8

2022-08-23 08:33:35  阅读:156  来源: 互联网

标签:typedef ch int long maxn 暑假 include 集训


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

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

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

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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有