首页 > 其他分享 >11.06

11.06

时间:2024-11-07 18:47:29浏览次数:1  
标签:ch int 复杂度 11.06 sqrt sigma define

发现自己对于一些不用动脑子的数据结构题还是有微弱的冲击力的。

A.BZOJ3722

为什么想不到????????????????????????

先不考虑 \(0\) 跑一遍,每个非叶结点取其子结点中 \(-1,-2\) 的众数,若相等则为 \(0\)。
此时若根节点为 \(-1\),那么其有偶数个值为 \(0\) 的儿子,对于每个 \(0\) 第一个对它子树中为 \(0\) 的叶子进行操作的人会将这个结点定为其对应的值,那么最优决策下根结点为 \(0\) 的儿子将会被 \(-1\) 和 \(-2\) 平分,此时根结点仍为 \(-1\),必输。
若根节点为 \(-2\),那么同 \(-1\) 类似,必胜,此时先手选择任意一个为 \(0\) 的叶子结点即可。
若根节点为 \(0\),则看其能否变为 \(-2\)。具体的,看先手能否把它的一个值为 \(-1\) 的儿子变为 \(0\),或者值为 \(0\) 的儿子变为 \(-1\),递归下去即可。

B.P5882 [CTSC2015] misc

若 \(v\) 在 \(s\rightarrow t\) 的最短路上,那么 \(\sigma_{st}(v)=\sigma_{sv}\cdot\sigma_{vt}\)。
那么我们枚举源点 \(s\),此时 \(R(v)=\sum\limits_{s \ne v \ne t} a_s\sigma_{sv}\frac{ a_t \sigma_{vt}}{\sigma_{st}}\),\(\sigma_{sv}\) 在最短路的过程中可以求出,后面的可以在以 \(s\) 为源点跑最短路形成的 \(DAG\) 上预处理出来。

C.Souvenirs

我:欸这个题怎么记得在萌熊的一次练习赛中见过,但是当时好像没有改,寄。

不过这回算是场切了。

首先一个很暴力的思路就是莫队的同时用数据结构维护最小差值,复杂度 \(m\sqrt n\log n\),极限数据要跑七秒多。
试图把数据结构换成 \(\text{bitset}\),时间复杂度 \(\frac{nm\sqrt n}{w}\),难评。
发现修改有 \(O(m\sqrt n)\) 个但是询问只有 \(O(m)\) 个,是不是可以根号平衡一下呢。
值域分块,发现修改和查询都是 \(\sqrt n\),时间复杂度 \(O(nm)\)。
块内套上一个数据结构维护呢,时间复杂度 \(O(m\sqrt n\log \sqrt n)\),由于 \(\log\sqrt n\) 和 \(\log n\) 相差无几,所以依然是寄掉的。
md 跟你爆了,每个块内开一个 \(\text{bitset}\) 维护答案,修改复杂度为 \(\frac{\sqrt n}{w}\approx5\),虽然不算很小,但是请相信 \(\text{bitset}\)!绝对卡不满,近似 \(O(1)\)。
但是现在删数不太好删,写个回滚莫队就行了。
写到一半会想起来 \(\text{bitset}\) 根本没有 _Find_prev 这个函数(差评),于是每个块内还要再开一个反着的 \(\text{bitset}\) 来实现 _Find_prev 操作。

时间复杂度 \(O(\frac{nm}{w}+m\sqrt n)\),实测能过。

好看的码
#include <bits/stdc++.h>
#define fr first
#define se second
#define Un unsigned
#define LL long long
#define pb push_back
#define pii pair<int,int>
#define pLi pair<LL,int>
#define pLL pair<LL,LL>
#define __ __int128
#define ld long double
#define VE vector<LL>
#define db double
#define Ve vector<int>

using namespace std;

inline int read()
{
	int x = 0,f = 1;char ch = getchar();
	while(!isdigit(ch)) (ch == '-') && (f = -1),ch = getchar();
	while(isdigit(ch)) x = x*10+ch-48,ch = getchar();
	return x*f;
}

const int N = 1e5+5,INF = 1e9;
int a[N],c[N],bl[N],ct,mn[N],mx[N],mnt[N],mxt[N],Ans[320],tmp[320],pos[N],B,stk[N],top,n,ans[N<<2];
bitset < 320 > b1[320],b2[320];
struct Que{int l,r,id;}que[N<<2];

bool cmp(Que x,Que y){return bl[x.l] == bl[y.l] ? x.r < y.r : x.l < y.l;}

inline void add(int p)
{
	if (b1[bl[p]][pos[p]]) Ans[bl[p]] = 0;
	else
	{
		int q = b1[bl[p]]._Find_next(pos[p]);
		if (q < B) Ans[bl[p]] = min(Ans[bl[p]],a[(bl[p]-1)*B+q+1]-a[p]);
		q = b2[bl[p]]._Find_next(B-1-pos[p]);
		if (q < B) Ans[bl[p]] = min(Ans[bl[p]],a[p]-a[(bl[p]-1)*B+B-q]);
		b1[bl[p]][pos[p]] = b2[bl[p]][B-1-pos[p]] = 1,mx[bl[p]] = max(mx[bl[p]],p),mn[bl[p]] = min(mn[bl[p]],p);
	}
}

inline void add1(int p)
{
	if (b1[bl[p]][pos[p]]) Ans[bl[p]] = 0;
	else
	{
		int q = b1[bl[p]]._Find_next(pos[p]);
		if (q < B) Ans[bl[p]] = min(Ans[bl[p]],a[(bl[p]-1)*B+q+1]-a[p]);
		q = b2[bl[p]]._Find_next(B-1-pos[p]);
		if (q < B) Ans[bl[p]] = min(Ans[bl[p]],a[p]-a[(bl[p]-1)*B+B-q]);
		b1[bl[p]][pos[p]] = b2[bl[p]][B-1-pos[p]] = 1,stk[++top] = p,mx[bl[p]] = max(mx[bl[p]],p),mn[bl[p]] = min(mn[bl[p]],p);
	}
}

inline int Q(int l,int r)
{
	for (int i = l;i <= r;i++) add1(c[i]);
	int res = INF,lst = 0;
	for (int i = 1;i <= bl[n];i++)
	{
		res = min(res,Ans[i]);
		if (lst && mn[i] < INF) res = min(res,a[mn[i]]-a[lst]);
		lst = mx[i] ? mx[i] : lst;
	}
	while(top) b1[bl[stk[top]]][pos[stk[top]]] = b2[bl[stk[top]]][B-1-pos[stk[top]]] = 0,top--;
	for (int i = 1;i <= bl[n];i++) mx[i] = 0,Ans[i] = mn[i] = INF;
	return res;
}

int main()
{
	n = read(),B = sqrt(n);
	for (int i = 1;i <= n;i++) a[i] = c[i] = read(),bl[i] = (i-1)/B+1,pos[i] = (i-1)%B;
	sort(a+1,a+n+1),ct = unique(a+1,a+n+1)-a-1;
	for (int i = 1;i <= n;i++) c[i] = lower_bound(a+1,a+ct+1,c[i])-a;
	int m = read();
	for (int i = 1;i <= m;i++) que[i] = {read(),read(),i};
	sort(que+1,que+m+1,cmp);
	int j = 1;
	for (int i = 1;i <= bl[n];i++)
	{
		for (int k = 1;k <= bl[n];k++)
			mx[k] = 0,Ans[k] = mn[k] = INF,b1[k].reset(),b2[k].reset();
		int ed = i*B,l = ed+1,r = ed;
		while(j <= m && bl[que[j].l] == i)
		{
			if (bl[que[j].r] == i) ans[que[j].id] = Q(que[j].l,que[j].r);
			else
			{
				while(r < que[j].r) add(c[++r]);
				for (int k = 1;k <= bl[n];k++) mxt[k] = mx[k],mnt[k] = mn[k],tmp[k] = Ans[k];
				while(l > que[j].l) add1(c[--l]);

				int res = INF,lst = 0;
				for (int k = 1;k <= bl[n];k++)
				{
					res = min(res,Ans[k]);
					if (lst && mn[k] < INF) res = min(res,a[mn[k]]-a[lst]);
					lst = mx[k] ? mx[k] : lst;
				}
				ans[que[j].id] = res;

				for (int k = 1;k <= bl[n];k++) mx[k] = mxt[k],mn[k] = mnt[k],Ans[k] = tmp[k];
				while(top) b1[bl[stk[top]]][pos[stk[top]]] = b2[bl[stk[top]]][B-1-pos[stk[top]]] = 0,top--;
			}
			j++,l = ed+1;
		}
	}
	for (int i = 1;i <= m;i++) printf("%d\n",ans[i]);
	return 0;
}

但是由于写到一半被拉去加训信息会考了,所以没打完,最后交的还是 \(O(m\sqrt n\log n)\) 暴力。
也算是把这题给补了。

标签:ch,int,复杂度,11.06,sqrt,sigma,define
From: https://www.cnblogs.com/ZepX-D/p/18533772

相关文章

  • [2024.11.06]NOIP 模拟赛
    不会tarjan不会广义串并联图……赛时T1看上去很可做。看到中位数首先想到二分。在二分的背景下,问题转化为求当前最多能使多少个元素大于等于某个定值。我们不妨先让所有的元素都选择\(a\)值,然后相当于要选择一段连续的\(b\)替换一些\(a\),要求最后总和最大。所以可以新设......
  • 2023.11.06 sh僵尸进程
    //简介:系统top显示中很多zombie僵尸进程,使系统进程数量已达到最大值35567。/查看sh子进程父进程全为基站产品的oam_2160二进程程序产生的(其原因为异常情况下,未正常处理系统调用:合理修改了pclose()调用)//参考文献https://blog.csdn.net/TiktokLiveTool/article/details/13211514......
  • CnWizards v0.9.8.603 Build 2011.06.06
    *单元清理增加对D2011的兼容。*字符串属性编辑器增加对WideString类型的支持。*向导专家修正一处Unicode环境下生成内容末尾字符串不完整的问题。*代码高亮修正快捷键未......
  • 2022.11.06
    今天是装系统的一天。我一个究极废物花了整整一天终于把deepin塞进了我的新U盘里,并且愉快地获得了一个启动U盘。linux系统光标有点不习惯,自带的输入法有点阴间,但晚上下了......
  • 【流水】2022.11.06
    想到果然【流水】比【闲话】更像是我的风格今天回到学校了在操场小做了一下抗原(我还站错队了,尬)感谢六班大哥值了十几天的日宿舍里面非常干净,实在是感动不久就会乱起......
  • 本周总结(11.06)
    本周主要完成了老年病的页面原型,软件开发案例的一些WinForm界面。完成了Redis的基础学习。下周计划:1、尽力完成一份自己的简历2、继续学习算法,Leetcode刷题3、自己的博......
  • Java学习——11.06
    Java的第一个大关。scanf函数的不同。这可能就是收到C语言的思维影响吧,Java中的scanf函数的运用和先前引用实例变量一样,要先new一个。例:Scannerscanner=newScann......