Logo __vector__ 的博客

博客

标签
暂无

P3377 【模板】左偏树 (非正解) AC 做法

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2023-02-28 23:06:33

upd: 在题解区翻到了和我一样的做法。

本想练习左偏树,但看到这道题之后自己乱口胡了一个非正解的做法。
写了写,结果没想到直接 A 了。。。。。

题解

考虑使用 $n$ 个小根堆,排序方式为按大小为第一关键字,输入顺序为第二关键字,升序排列。

至于记录每个数字在哪个堆,用并查集维护。

合并的时候暴力合并,每次把小的堆加入大的堆。

删除的时候直接将要删的数弹出,然后标记上已删除。

结束。

关于时间复杂度:
自我感觉是 $O(n \log^2 n)$ 的。

实际运行时间与正解没多少区别。

Code

#include <bits\/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,m;
int fa[maxn];
bool del[maxn];
priority_queue<pair<int,int> ,vector<pair<int,int> >,greater<pair<int,int> > > q[maxn];
int find(int x)
{
    return fa[x]==x?x:fa[x]=find(fa[x]);
}
void merge(int x,int y)
{
    if(del[x]||del[y])return;
    int idx=find(x);
    int idy=find(y);
    if(idx==idy)return;
    if(q[idx].size()>q[idy].size())
    {
        while(!q[idy].empty())
        {
            q[idx].push(q[idy].top());
            q[idy].pop();
        }
        fa[idy]=idx;
    }
    else
    {
        while(!q[idx].empty())
        {
            q[idy].push(q[idx].top());
            q[idx].pop();
        }
        fa[idx]=idy;
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int ai;
        scanf("%d",&ai);
        q[i].push(make_pair(ai,i));
        fa[i]=i;
    }
    int op,x,y;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%d",&x,&y);
            merge(x,y);
        }
        else
        {
            scanf("%d",&x);
            if(del[x])
            {
                printf("-1\n");
                continue;
            }
            int idx=find(x);
            printf("%d\n",q[idx].top().first);
            del[q[idx].top().second]=1;
            q[idx].pop();
            
        }
    }
    return 0;
}

2023.3.1 闲话

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2023-03-01 22:01:08

RT.
CF 上紫之前每天发一遍。

又是耗在 DS 上的一天。

感觉啥也没干。

看到犇犇有人说某人在红客论坛上 【数据删除】,电脑被 ddos 炸 + 被开了 qq 私聊记录。

想起小学的时候,某个 sb 同时找我和某个好友的岔(具体地说就是我没惹他,他故意挑衅我们俩)

然后我的好友就搞到了几个病毒告诉我了他的 IP 地址,让我去搞他。

当然我没同意。

现在的初中同学也有不少人以为 OIer = Hacker

【ZROI noip10连day2】T1 题解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-09-04 23:08:23

本题解尚未提交代码,不一定正确。

做法

先来考虑一下,已知每种砝码是否出现的情况下怎么判定能否凑出 $x$。

很容易写出一个指数级的爆搜:以当前重量 $x$ 为参数,枚举砝码从 $x$ 中减掉递归下去,看能否递归到 $0$。

复杂度:算不出来。预计得分:$0$ 分。

这个爆搜之所以是指数级,是因为重复搜索了很多节点,所以搜完一个节点,就把这个节点的答案记录下来,就优化到 $O(m)$ 了。

每次询问就临时统计一下询问区间每种砝码是否出现,用得到的信息跑记忆化搜索。

复杂度:$O(qn+qm)$。预计得分:$50$ 分。

题目说了,砝码的数值不会超过 $10$ 种。
而能否凑出一个数,只和这个数的数值以及砝码拥有状态决定。

要凑的数最大是 $10^5$,而砝码拥有状态有 $2^{10} = 1024$ 种可能性。

可以把每种可能都枚举一下,进行预处理。

每次查询的时候,线段树维护区间每种砝码是否出现,然后用得到的信息直接查表。

复杂度:$O(1024m+q \log n)$,预计得分:$100$ 分。

Code

正在写。

【济南qbxt集训 CSP-S考前综合强化系列模拟赛】题解

How to AK zhqwq-CSPS模拟赛

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-10-16 15:23:27

题外话

总结成绩:寄了。

T1-sbt

直接按照题意模拟,通过观察可以发现,向左走,变小,向右走,变大。
其实就是一个 BST。

T2-gift

实际不需要知道每个颜色出现多少次,只需要知道有多少个元素出现奇数次,有多少个出现偶数次。
设 $f_{i,j}$ 为前 $i$ 个有 $j$ 个颜色出现奇数次的方案数。
转移的时候,想一下下一个颜色是什么。如果下一个颜色在这 $j$ 个现在出现奇数次的颜色里面出现过,那么下一个状态出现奇数次的颜色数相较于现在减一。 否则下一个出现奇数次的颜色书相较于现在加一。

转移:f[i+1][j-1]+=f[i][j]*jf[i+1][j+1]+=f[i][j]*(m-j)

代码在写。

CSP-S2022 游记

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-10-29 21:45:44

因为新冠取消了,没去成

2022 期中考试游寄-初二上学期

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-11-03 21:01:57

Day-?

因为傻逼 COVID-19(新冠什么时候死),去不了 CSP,被迫开始复习 whk。

Day-1

上午集中复习语文政治,中午整了一会英语。

下午开始考英语。

前面题比较简单,顺序做题,很快做完了选择题。看着剩下的题也比较水,就继续往下做,忽然遇到一道题,不会了,蒙了个答案(然而最后错了,但只有 1 分),然后还是较为顺利的做完了,没啥好说。

Day-2

第一节考语文。

前面一堆文常,不少没背,寄。

阅读理解倒是挺快。

用了 1h 左右来到了作文。

一看题目 “窗外”。

想着应该比较好写,而且只要求 600字。

我就直接上去写,一下子写了 900 多字,看着时间快到了,就赶紧收尾。

重新读了一下,震惊发现似乎有点跑题,但是只有第一句话跑了,后面没有,不知道阅卷人会不会脚下留情【惊恐】

考完对答案,果然错了好几道文常。

第二节 zz。

先做完弱智选择。

然后看大题,然后............一顿狂写,手都写麻了。

最后卡着点做完。

一对答案,爽死了,12 分的题理解错了,寄。

第三节历史。

比较有把握,感觉难度还好,但是考完后集体评价很难(?)

第四节生物。

一堆选择用 0.5h 做完。

后面也都是正常难度,还是卡着点做完。

Day-3

第一节数学。

考数学的时候是最紧张的,如果最强的科考砸了就彻底完了。

开始做选择,用既定策略,快速秒掉前 11 题(然而太着急了,其中一道题看错了,现在后悔不已),稳定了心态,然后 做 T12,T12 果然又是一道几何证明题,我在将所有已知条件列出来之后,大概使用 bfs 的方式向前递推,竟然在 1 分钟内证明了所有的正确结论。

选择题切完了,开始干填空,前面一些题比较水,都直接秒了,但是 T20 似乎不那么好做,感觉做下去意义不大,先 skip 了。

然后大题一路切到 T25,还没遇到障碍。

做 T26,看时间还剩下 1h,很充足,我决定认真思考这道题。

我先是尝试利用两个三角形全等直接证明,却发现总是少一个条件,用任意两个可能的三角形都是这样。

于是我决定尝试对缺少的条件进行证明。

先是看已知条件,我发现有两组分别相等的角,遗憾的是它们不在两个可能全等的三角形里。

继续找,我忽然我找到了两个用已知条件可以直接证明的全等三角形,但遗憾的是它不能证明题目给定结论。

但是它肯定有用,继续往下推,我发现用这两个全等三角形可以进一步地推出两条边相等,再进一步地推出另外两个角相等,再进一步地推出另外两条边相等。

然后惊喜的发现,它正好补上了之前缺少的用于证明三角形全等的条件。

然后成功证明三角形全等,进而证明了题目结论。

开始干 T27(最后一题),还剩下 0.5h。

开始找等量关系,想了一会八字模型,发现不行。

然后发现是个手拉手模型,然后又发现两个全等三角形,证明成功。

数学考试结束。

对答案发现,除了填空题一道不会,还有一道选择题因为看错题写挂,其余全对。

然后考地理

题水,没啥好说。

考试结束后

老师曰:“在芝罘中学,期中考试不是你的终点,中考才是,所有都是为了准备中考...........所以,今天晚上的作业:&%$%^*&^%$#$%抄 3 编,默一遍,外加一份报纸”

啊!怎么考完了还有一堆作业!

CSP-S2022 vp 游记

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-11-05 15:42:26

坐标 SD,因疫情没去成,就在家 vp。

=======比赛历程=========

开始 vp,先通读题面,看 T1 貌似可做,应该是 dp,就把想法写了下来,然后去看 T2。

T2 看到一个 “策略” 先是很震惊,T2 就出博弈论。结果仔细一看,每次只进行一轮。那不就成水题了,分析了一下,得出了一个需要分正负讨论的 $O(n \log n)$ 做法,用 6 个 ST 表进行维护。

然后开始写。

经过大约 0.5h,写完了,一测样例,第一个样例过了,但第二个没过。看着 150 行左右的代码,感觉很寄。

没办法,去查错吧,用了 10min 左右,发现查询部分少写了一个,修改之后通过样例。

然后紧接着通过了第一个大样例,然而第二个大样例 RE 了。

看了一下代码,并没有发现数组开小,有些紧张。又看了 5min 左右,发现 ST 表忘判越界了。

修改之后通过所有大样例。

然后开始刚 T1。

我快速写出了一个 $O(n^2)$ 的 dp 做法。

写完之后发现没过样例。

把样例画了出来,思考了 20min,发现 dp 转移方程错了。

然后紧急改,增加了一维状态,但还是 $O(n^2)$。

改完之后过了两个小样例。

但是大样例死掉了。

发现是少计算了一个点,但是不知道怎么改。

经过 20min 的思考,发现我的状态没错,但是转移有问题。

又改了改,但大样例还是死掉。

最后放弃了这个做法,去写暴力。

暴力还是比较好写,我很快就写出了一个 $O(n^4)$,使用 floyd 预处理然后暴力枚举四个点的做法,顺便加了一些剪枝。

然后扔掉 T1。

之后去看 T4

读完题,先去解决最简单的 $k = 1$。

这种情况下不能跳点,所以用树上差分 + lca 就行了。

用了 10min 写完树剖,解决掉了 $k=1$,复杂度 $O(n \log n)$。

看 $k=2$ 和 $k=3$。

发现可以在树上进行 dp,我赶紧写完了一个简单 dp,一测,发现大样例挂了。

经过分析,发现我的 dp 少计算了一些东西。

然后进行修改。

又过了 10min 左右,过掉了大样例,此部分复杂度 $O(n^2)$。

然后去看 T3。

暴力死活调不出来,在调试过程中比赛结束。

======结果===========

70 + 90 + 0 + 36 = 196。

第一题可以说是暴力出奇迹。第二题不知道原因,WA 了两个点,T4 正常。

不知道如果 SD 正常举行,能不能省一。

======UPD=============

官方数据:70+95+0+36=201。
如果正常举行应该有蓝钩吧........ 看这样子蓝钩线得上 300

======UPD=============

过 6 级线了

CSP-J2022 VP游记

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-11-05 18:57:50

虽然是 S 组。

  • T1
    快速幂秒了
  • T2
    随手推了推,推出了 $p+q$ 和 $pq$ 的值。
    然后二分了一下就过了。
  • T3
    模拟写挂了,和去年一样。
  • T4
    简单 dp。

100+100+0+100=300pts,菜死了。

真是丢死人了。

ABC276 D题解

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2022-11-06 22:30:39

做法

想一想除法操作的本质。

对于一个数除以 $2$,就是使这个数的因数 $2$ 的数量减一。
举个简单的例子,$8$ 分解之后有 $3$ 个 因数 $2$。将其除以 $2$ 之后,变成 $4$,只有 $2$ 个因数 $2$ 了。

除以 $3$ 同理。

而所有数相等,实际上就是所有数的每种因数的数量分别相等

而现在只能让每个数的因数 $2$ 或 因数 $3$ 的数量减少。

所以最后操作完的时候,如果取最优值,那么最终所有数的每种因数数量,都是这种因数在所有数之中出现次数的最小值。

所以先记录下因数 $2$ 或 $3$ 在所有数中出现的最少次数,记为 $com_2,com_3$。

设第 $i$ 个数出现了 ${cnt2}{i} $ 次因数 $2$,${cnt3}{i}$ 次因数 $3$。

答案就是 $\sum_{i=1}^{n} ({cnt2}{i} - com_2 + {cnt3}{i} - com_3)$。

那无解怎么判定?

如果两个数因数 $2,3$ 出现的次数不同,可以通过一些操作来调整成相同。

但是如果还出现了别的因数呢?

如果还出现了别的因数,那么这个因数必须在所有的数中出现次数相同,否则无解,因为无法调整。

最后复杂度,扫一遍,扫的过程中每个数计算对数次。

Code

#include <bits\/stdc++.h>
using namespace std;
const int maxn=1005;
int n;
int a[maxn];
struct Cnt
{
	int tw,thr,els;
}cnt[maxn];
int main()
{
	scanf("%d",&n);
	int es=0;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		while(a[i]!=1)
		{
			if(a[i]%2 && a[i]%3 && es!=0 && a[i]!=es)
			{
				printf("-1\n");
				return 0;
			}
			if(a[i]%2&&a[i]%3)
			{
				es=a[i];
				cnt[i].els++;
				break;
			}
			if(a[i]%2==0)
			{
				a[i]\/=2;
				cnt[i].tw++;
			}
			if(a[i]%3==0)
			{
				a[i]\/=3;
				cnt[i].thr++;
			}
		}
	}
	for(int i=1;i<n;i++)
	{
		if(cnt[i].els!=cnt[i+1].els)
		{
			printf("-1");
			return 0;
		}
	}
	int common2=1e9,common3=1e9;
	for(int i=1;i<=n;i++)
	{
		common2=min(common2,cnt[i].tw);
		common3=min(common3,cnt[i].thr);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans+=cnt[i].tw-common2;
		ans+=cnt[i].thr-common3;
	}
	printf("%d",ans);
	return 0;
}  
共 320 篇博客