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

暑假集训8

时间:2022-08-23 08:11:10浏览次数:46  
标签: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,集训
From: https://www.cnblogs.com/Chencgy/p/16614868.html

相关文章

  • 雅礼NOIP2018集训 day5 赛
    雅礼NOIP2018集训day5赛题面由于出题人思维枯竭所以想不出好玩的背景。有n个物品,第i个物品的价格是vi,有两个人,每个人都喜欢n个物品中的一些物品。要求选出正......
  • 雅礼NOIP2018集训 day3 u
    雅礼NOIP2018集训day3u题面考虑一个\(n*n\)的矩阵\(A\),初始所有元素均为\(0\)。执行\(q\)次如下形式的操作:给定\(4\)个整数\(r,c,l,s\),对于每个满足\(x\in[r,r+l),y\in......
  • 暑假集训七[One, 砖块,数字,甜圈]
    暑假集训七和迪哥推了一个多小时,终于被贯通了方法一here#include<bits/stdc++.h>#defineLLlonglong#defineReregisterint#defineLDlongdouble#define......
  • 暑假集训七[One,砖块,数字,甜圈]
    暑假集训七您总算更新当天的东西了啊。A.One典型的约瑟夫问题,\(t<10,n\leq1e7\)数据范围需要我们用线性算法。考虑每次去掉一个人后都重新编号,把编号改为\([0,n)\)......
  • 暑期集训7
    130rank39T1:T2:暴力模拟T3T4:【甜圈】线段树(hash区间加乘或者直接维护区间信息)T4:给你n个盒子,初始为空,支持t个操作,每次(l,r,xi),表示在[l,r]区间编号的盒子有序放上x......
  • 暑假集训7(建议等我改完再点开)
    A.One用vector把out的及时删掉,然后就可以直接加位置了,STL真好用,不过它T了……#include<bits/stdc++.h>usingnamespacestd;intT,n;vector<int>a;inline......
  • 集训3/4总结
    这几次考试题难度和在家集训五天的难度差不多,但是考试状态好了很多,故成绩还看得过去。感觉基本集训几天第一次学的算法都没太学懂,还需要自己去复习。上新课的速度没我想的......
  • 2022/8/20暑假学习日记
    1问题:合格的软件工程师,有什么具体的标准吗?还是说能写代码,又能发现问题解决问题就可以成为了呢?我们现阶段可以从哪方面开始培养自己的开发思维和能力,向工程师迈进?回答:作为......
  • 集训总结
    集训总结收获学习了一些从未接触的数据结构:线段树,树状数组,单调栈,单调队列可以实现一些基本操作,但与灵活运用还有一定距离,也无法与其他算法相结合使用提升了图......
  • A层邀请赛6 && 暑假集训加试1
    A.菜暴力做法:2^n枚举哪些人是正向上菜的,然后记录答案。#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintmaxn=20;constin......