首页 > 其他分享 >题目记录(一直更新

题目记录(一直更新

时间:2024-10-29 12:43:06浏览次数:1  
标签:prime 题目 迭代 记录 int sum 元素 更新 询问

OI记录(持续更新

P2568 GCD

题意:

给定正整数 \(n\),求 \(1\le x,y\le n\) 且 \(\gcd(x,y)\) 为素数的数对 \((x,y)\) 有多少对(\(n\leq10^7\))

题解:

注意,可以不用莫比乌斯反演,单纯的欧拉函数便可以解决,首先列出式子:

\[\sum_{p\in prime}\sum_{i=1}^{n}\sum_{j=1}^{n}(gcd(i,j)=p) \]

接着转化式子,gcd里的\(i,j\)同除\(p\),再换元一下:

\[\sum_{p\in prime}\sum_{i=1}^{\lfloor \frac {n}{p} \rfloor}\sum_{j=1}^{\lfloor \frac {n}{p} \rfloor}(gcd(i,j)=1) \]

然后我们可以观察到\(gcd(i,j)=1\)代表的是互质,如何转化到可以计算呢,我们假设\(j\)枚举到\(i\),这样就可以用欧拉函数,然后讨论一下改成这个就只是有序变为无序,然后会有2倍的差距,然后考虑\(i=j\)的时候会被统计两次但是因为\(gcd(i,j)=1\) 只有\(i=j=1\)时有贡献,在\(\sum_{p\in prime}\)这层循环下减个1,于是为:

\[\sum_{p\in prime}(\sum_{i=1}^{\lfloor \frac {n}{p} \rfloor}(2\sum_{j=1}^{i}(gcd(i,j)=1))-1) \]

然后发现这个\(\sum_{j=1}^{i}(gcd(i,j)=1)\)就是欧拉函数\(\varphi(x)\):

\[\sum_{p\in prime}(2\sum_{i=1}^{\lfloor \frac {n}{p} \rfloor}\varphi(i)-1) \]

具体在程序中刚开始用欧拉筛预处理出来要用到的欧拉函数值和所有的质数,接着预处理出来一个前缀和。

最后枚举所有的质数,求\(2sumphi[n/p]-1\)。

因为这题始数学题,AC code较为简单:

#include<bits/stdc++.h>
#define int long long
#define N 10000009
using namespace std;
int n;
int phi[N],sumphi[N];
bool pri[N];
int prime[N],cnt;
int answ=0;
void euler()
{
	phi[1]=1;
	for(int i=2;i<=10000002;i++)
	{
		if(!pri[i]) prime[++cnt]=i,phi[i]=i-1;
		for(int j=1;j<=cnt;j++)
		{
			if(i*prime[j]>10000002) break;
			if(i%prime[j]==0){
				pri[i*prime[j]]=1;
				phi[i*prime[j]]=phi[i]*prime[j];break;
			}
			pri[i*prime[j]]=1;
			phi[i*prime[j]]=phi[i]*phi[prime[j]];
		 } 
	}
	for(int i=1;i<=10000002;i++)
		sumphi[i]=sumphi[i-1]+phi[i];
}
signed main()
{
	scanf("%lld",&n);
	euler();

	//cout<<cnt;
	for(int i=1;i<=cnt;i++)
	{
		if(prime[i]>n) break;
		//cout<<sumphi[n/prime[i]]<<endl;
		answ+=(2*sumphi[n/prime[i]]-1);
	}
	printf("%lld",answ);
}

P1640 [SCOI2010] 连续攻击游戏

题意:

给定\(n\)个物品,每个物品有两个属性值,每种物品只能选取其中一个属性,并且每个物品只能用一次。现在要从属性\(1\)开始,选取物品,问最多能选取多少个。

题解:

二分图忘了,这道题是二分图板子,是用来锻炼二分图的,二分图匹配的匈牙利算法有一个很棒的性质:前面已经被匹配过的点不会失配。然后我们进行套路的建图,每个物品连两条边到他的属性值上,然后以属性值作为右部点,依次跑二分图匹配,直到失配便终止循环。

值得一提的是,这道题有些不适合网络流解法,二分答案跑网络流会超时,但是可以玄学先增广序号在前的点,这样也能得到正确答案。

因为用的是匈牙利算法,所以代码简单:

#include<bits/stdc++.h>
#define N 1145141
using namespace std;
int match[N],n;
vector<int>tu[N];
bool vis[N];
stack<int>V;
bool dfs(int now)
{
	//cout<<now<<endl;
	for(auto too:tu[now])
	{
		if(!vis[too])
		{
			vis[too]=1;
			V.push(too);
			if(!match[too]||dfs(match[too]))
				{
					match[too]=now;
					return true;
				}
		}
	}
	return false;
}
int read()
{
	int ans=0;
	char c=getchar();
	while(c<'0'||c>'9') c=getchar();
	while(c>='0'&&c<='9')
	{
		ans=10*ans+c-'0';
		c=getchar();
	}return ans;
    /*int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;*/

}
int main(){
	
	n=read();
	for(int i=1;i<=n;i++)
	{
		int x=read(),y=read();
		tu[10000+i].push_back(x);
		tu[10000+i].push_back(y);
		tu[y].push_back(10000+i);
		tu[x].push_back(10000+i);
	}
	for(int i=1;i<=10000;i++)
	{
		
		while(!V.empty()){
			vis[V.top()]=0;
			V.pop();
		}
		if(!dfs(i)){
			printf("%d",i-1);
			return 0;
		}
	}
	printf("10000");
}

容器 setmultiset

setmultiset 代表有序集合和可重有序集合,包含在 set 库中。

关于迭代器:

迭代器就是指向一个元素的指针,例如用 int 类型定义的 set 集合里指向开头元素的迭代器一般表示为:

set<int>::iterator it = s.begin();

it + 1 指向下一个元素,it - 1 指向上一个元素(如果这个集合中存在上一个或下一个元素的话)。

  • s.begin() 是指向 s 开头元素的迭代器。
  • s.end() 是指向 s 末尾元素的下一个内存位置的迭代器,所以如果要查末尾元素,一般是引用 s.end() - 1

注意这里 +1-1 的时间复杂度都是 O(log n)

有何作用?除了遍历集合元素外,setmultiset 都是有序集合(默认从小到大,可以用定义优先队列的方法定义这个东西),所以这就相当于是一个平衡树了,是不是很棒?平衡树可以干很多事呢。

如何把迭代器换为可以直接输出的该元素的值?加个星号,即 *it

可以用减法查看当前是第几个。

关于操作:

定义如 int 类型用 set<int> smultiset<int> s

具有以下基础操作:

  • s.clear()
  • s.empty()
  • s.size()
  • s.insert(x) 代表插入元素 x,如果是重复的元素,set 不会插入,multiset 会插入。
  • s.find(x) 表示查找集合里等于该元素的迭代器(返回第一个),不存在返回 s.end()
  • 具有二分函数 s.lower_bound(x)s.upper_bound(x),代表查询大于等于 x 和大于 x 的元素里最小的一个,返回迭代器。
  • s.erase(x) 代表删除所有等于 x 的元素或者删除 x 迭代器所指的元素。特别注意的是,如果只删去一个等于 x 的元素,可以执行:
if((it=s.find(x))!=s.end()) s.erase(it);//代表先找指向x的迭代器,如果x存在,就删去
  • s.count() 返回集合中等于 x 的元素个数。

上面函数的复杂度除了 s.count()s.erase()O(k + log n),其余都是 O(log n)

当然,平衡树别写set,时间和正确性都容易炸(时间必炸)。

组合数预处理

先预处理\(C_{i}^{0}=1\)然后根据\(C_{i}^{j}=C_{i-1}^{j-1}+C_{i}^{j-1}\)递推出所有组合数:

for(int i=0;i<=3000;i++) c[i][0]=0;
	for(int i=1;i<=3000;i++)
		for(int j=1;j<=i;j++) c[i][j]=(c[i-1][j-1]+c[i][j-1])%MOD;

10.23正睿模拟赛T3记录

题意:

给定一张 \(n\)个点,\(m\)条边的有向无环图

进行 \(q\)次询问,每次询问给定 \(s,t,l,r\)。问若只保留编号在$ [l,r]$ 之间的边,\(s\) 能否到达 \(t\)。

题解:

妙妙题。

先给给询问搞个编号,离线下来做。

首先我们要用\(bitset\)进行辅助记录,首先记录一个\(g[m]\),单个\(g[i]\)记录的是编号为\(i\)的边在所有询问里的存在情况(\(bitset\)存的)。

具体的计算我们搞一个扫描线,对于每一个询问,在边编号的\(tag\)上记东西,在\(l\)位置记上这个询问编号,\(r+1\)位置也记录这个询问编号,然后就定义一个\(bitset\) \(Q\),扫一遍这个\(tag\),每回先给\(Q\)在所有目前位置上所有询问编号在对应的位置取反,然后把这个\(Q\)赋值给对应的\(g[i]\)。

然后就是\(f[n]\)了,对于每一个结点,单个\(f[i]\)记录的是每一个询问的\(s_i\)在只能有当前询问存在的边时到这个点的连通性(同样用\(bitset\)存)。

首先初始化给每个询问的\(s_i\)的\(f[s_i]\)对应的关于本身\(s_i\)的存在性命名为1(因为自己肯定和自己连通嘛)。

然后考虑是DAG,我们可以转移,有边\((u,v)\),编号\(i\),可以使得\(f[u]\)贡献给\(f[v]\)一个\(f[u] \and f[v]\)(贡献的形式是或),在拓扑排序的过程中转移,因为在所有通向自己的边处理完后,这个点也处理完了。

但是这样就是询问比较多,空间容易炸,但是因为询问和询问间不打扰,所有我们可以\(B\)个询问\(B\)个询问的处理,这样每个\(bitset\)的长度也就只有\(B\),空间也就不会炸,就处理完了。

最后就对于每个询问输出答案即可。

总结:

  1. 用\(bitset\)优化时间和运算
  2. 考虑在拓扑排序上进行\(dp\)转移
  3. 用扫描线思想处理问题
  4. 空间炸了如果里面各部分互不相干可以分块计算
  5. 多个数组联合计算

\(over\)

拉格朗日插值

还没记。

小纪录

关于树上面统计答案时,到了以\(u\)为根的子树上,假如这个统计答案的方式需要是从\(u\)出发的两个不同路径的贡献和的最大值,我们不仅可以把最大和次大的贡献给和一块,还可以不断更新单个从u出发的最大贡献过程中更新这个俩路径合并在一起的最大值,不如现在单个路径最大贡献计算到了\(v\)之前的(不包括\(v\)),我们计算经过\(v\)的单个路径和\(u\)目前单个路径最大贡献的和贡献即可,然后继续更新单个路径最大贡献。

线段树分治记录

更明白的应该说是在线段树上离线查询,适用于那种不支持删除但是支持撤销的东西可以用线段树来辅助,具体来说比如一个东西,你要加进去一个东西,过一段时间再删除这个东西,也就是说不是撤销,不妨为这个时间序列开一个线段树,每回区间操作都记录这个东西存在的区间,这样在线段树上就可以保证这个东西创建和删除可以在一块儿进行。

然后有些题目不会给你明示,就需要各种观察和转化,比如求对于每个元素我们就删除它求剩下的元素的答案,就可以把这些元素当成时间序列排一块,对于不删这个元素的两个(或一个)区间进行标记操作,就可以转化为多次撤销和增加然后求答案。

当然一些题目中那些不要局限在题目中的对哪个东西询问来盲目地进行线段树分治,可能不是对这玩意进行线段树分治,要勤进行转化。

标签:prime,题目,迭代,记录,int,sum,元素,更新,询问
From: https://www.cnblogs.com/huanghezhe/p/18512742

相关文章

  • 实时语音转写技术:思通数科AI多模态平台赋能法庭审理,为庭审记录带来新体验
    一、系统介绍系统具备强大的特征提取和语音处理能力,利用美尔频谱系数(MFCCs)等算法进行高精度声学建模,并结合语言模型确保转写内容的上下文完整性。支持多语种识别、讲话人辨识、实时记录等功能,为多语言法庭环境及国际化庭审提供技术支持。平台还结合了Bert算法进行特征深度提取和......
  • 人工智能教育技术学 第七次课程记录
    1.提示语设计*明确任务:清楚地告诉AI要完成的任务,例如“写一篇关于人工智能的文章”。具体要求:提供具体的要求,如文章的主题、字数、风格等。使用精确动词:选择精确和富有活力的动词,如阐释、重新诠释、简化、丰富等,来表达对AI的要求。引导AI:通过提示语引导AI按照特定的方......
  • Android13 通过OTA升级更新系统默认设置
    系统进行OTA升级时更改默认设置的详细步骤在进行系统的OTA(Over-The-Air)升级过程中,如果需要对系统默认设置进行更改,以确保升级后的系统能够应用新的默认配置,那么需要执行一系列关键步骤。以下是详细的操作指南:修改设备Overlay资源首先,需要定位到设备特定的Overlay资源文件......
  • C#学习 [类型系统] 记录(13)
    要求C#9.0.概念记录是一个类或结构,它为使用数据模型提供特定的语法和行为。使用场景想要定义依赖值相等性的数据模型。例如:想要判断两个对象实例值是否想等,这个时候用record就更加合适。想要定义对象不可变的类型。值相等性值相等性是指如果记录类型的两个变量类......
  • 一些题目
    一些最近刷到的好题,还有一些没见过的处理方式。原题:FunctionQuery定义\(f(x)=(x\oplusa)-b\),其中\(a,b\)是给定的参数。给定\(n\)个变量,\(x_1,x_2,x_3,\dots,x_n\),给出\(q\)组询问,对于每组询问,给定\(a,b\),请你输出一个\(i\),满足\(i\in[1,n)\),且有\(f(x_i)\times......
  • 记录2024年9-10月面试情况
    记录2024年9-10月面试情况开篇闲聊,me,来自山河四省,奈何功力有限,求学于东北,现工作三年,从事JAVA后端开发,今年6月底裸辞,直接碰壁,回老家玩耍2个月,九月初来杭,继续找,玩够了,但很不顺,是非常的不顺,各大招聘软件,投,投,投,不读,已读,不回,经验不足,薪资给不到,项目不匹配..............emo,em......
  • 【记录一下】lazarus多线程的用法
    网友“蓝天白云”在qq群问lazarus多线程的问题,以下代码是“啊D”给出的,但编译出错。procedureTForm1.Button2Click(Sender:TObject);beginmemo1.Text:='start...';TThread.CreateAnonymousThread(procedurevari:integer;beginSleep(1000);for......
  • Python 学习记录(3)
    数据Pandas对数据帧各列的运算importseabornassnsimportpandasaspd#从Seaborn当中导入鸢尾花数据帧,并处理iris_df=sns.load_dataset("iris")X_df=iris_df.copy()X_df.rename(columns={'sepal_length':'X1','sepal_width'......
  • 苹果和安卓在系统更新政策上有哪些不同_1
    苹果(iOS)和安卓(Android)在系统更新政策上存在显著差异,这些差异对用户体验、安全性和设备寿命产生重要影响。苹果提供定期且统一的更新,覆盖所有支持的设备,确保安全性和功能的一致性。苹果和安卓在以下方面的差异:1.更新发布的一致性;2.更新的控制和自定义;3.安全更新和漏洞修复;4.操作系......
  • ASP.Net Core 8 Web API整合Swagger UI并进行模块分组吃屎般瞬间记录
    一、开发环境开发工具:VisualStudio2022工程模板:ASP.NetCore8WebAPI工程(官方标准的).Net环境:.NetCore8.0NuGet依赖:Swashbuckle.AspNetCore6.9.0(UI用的默认的UI界面,可以自由选择其他的UI界面)二、基本概述参考了网上很多大佬的帖子,实现基本就两种:1、用自定义At......