24.4.7周报

news2025/1/23 2:21:33

星期一:

再学kmp,学的最明白的一次

贴道kmp的题                         洛谷传送门

思路:答案为n-ne【n】,把字符串画两遍理解一下

思路:最长周期,复制一遍过后要求覆盖原字符串,及字符串中非周期的后缀与周期的部分前缀相等,因为周期要最长,所以后缀要最短,即求大于0的情况下最短相等前后缀,依然能用next数组求,不断j=ne【j】即可,记得压缩路径,不然会 T

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int ne[N];
void solve(){
	string s; cin >> n >> s; s=" "+s;
	ne[1]=0;
	for(int i=2,j=0;i<=n;i++){
		while(j && s[i]!=s[j+1]) j=ne[j];
		if(s[i]==s[j+1]) j++;
		ne[i]=j;
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		if(!ne[i]) continue;
		int j=ne[i];
		while(ne[j]) j=ne[j];
		ne[i]=j;               //路径压缩
		ans+=i-j;
	}
	cout << ans;
}

星期二:

历时两天,终于拿下这题                    atc传送门

思路:kmp加上状压板子,不难,但做这题的时间跨度很长

sa【i】【j】表示字符串 j 接在 i 后面实际增加的长度,用kmp预处理出来

wa了很多发是因为去掉被包含的字符串时,一边遍历vector一边erase,后来加了个临时储存的vector,一个个添加到ves里就过了,教训是谨慎使用erase,特别是遍历时

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
vector<string>ves;
int ne[N];
int sa[22][22];
ll dp[1<<21][22];
bool check(string s1,string s2){
	int m=s1.size(),n=s2.size();
	s1=" "+s1,s2=" "+s2;
	ne[1]=0;
	for(int i=2,j=0;i<=n;i++){
		while(j && s2[i]!=s2[j+1]) j=ne[j];
		if(s2[i]==s2[j+1]) j++;
		ne[i]=j;
	}
	for(int i=1,j=0;i<=m;i++){
		while(j && s1[i]!=s2[j+1]) j=ne[j];
		if(s1[i]==s2[j+1]) j++;
		if(j==n) return 1;
	}
	return 0;
}
int ask(string s1,string s2){
	string s=" "+s2+s1;int n=s.size()-1;
	ne[1]=0;
	for(int i=2,j=0;i<=n;i++){
		while(j && s[i]!=s[j+1]) j=ne[j];
		if(s[i]==s[j+1]) j++;
		ne[i]=j;
	}
	return ne[n];
}
void solve(){
	cin >> n;
	vector<string>tmp;
	for(int i=1;i<=n;i++){
		string s; cin >> s;
		tmp.push_back(s);
	}
	sort(tmp.begin(),tmp.end());
	tmp.erase(unique(tmp.begin(),tmp.end()),tmp.end());
	for(int i=0,sz=tmp.size();i<sz;i++){
		bool if1=1;
		for(int j=0;j<sz;j++){
			if(i==j) continue;
			if(check(tmp[j],tmp[i])) if1=0;
		}
		if(if1) ves.push_back(tmp[i]);
	}
	n=ves.size();
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(i==j) continue;
			sa[i][j]=ves[j].size()-ask(ves[i],ves[j]);
		}
	}
	for(int mask=0;mask<=(1<<n);mask++){
		for(int i=0;i<=n;i++) dp[mask][i]=1e18;
	}
	for(int i=0;i<n;i++) dp[1<<i][i]=ves[i].size();
	for(int mask=0;mask<(1<<n);mask++){
		for(int i=0;i<n;i++){
			if(!(mask&1<<i)) continue;
			for(int j=0;j<n;j++){
				if(mask&1<<j) continue;
				int nmask=mask|(1<<j);
				dp[nmask][j]=min(dp[mask][i]+sa[i][j],dp[nmask][j]);
			}
		}
	}
	ll ans=1e18;
	for(int i=0;i<n;i++) ans=min(dp[(1<<n)-1][i],ans);
	cout << ans;
}

下午蓝桥模拟赛,打的还行

一道全排列暴力的题,没有思路,贴上是因为对于飞机降落的时间判断失误,痛失60分,贴着给自己长个记性

思路:区间dp,遇到两次都是用暴力冲过去的

dp【i】【j】表示区间 i,j 是否可翻转

转移:若s【i】> s【j】,dp【i】【j】=1,否则若s【i】== s【j】,dp【i】【j】=dp【i+1】【j-1】

代码如下:

ll n;
string s;
ll dp[5050][5050];
void solve(){
	cin >> s;
	n=s.size();s=" "+s;
	for(int i=1;i<n;i++)
		if(s[i]>s[i+1]) dp[i][i+1]=1;
	for(int len=3;len<=n;len++){
		for(int l=1;l+len-1<=n;l++){
			int r=l+len-1;
			if(s[l]>s[r]) dp[l][r]=1;
			else if(s[l]==s[r]) dp[l][r]=dp[l+1][r-1];
		}
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++)
			ans+=dp[i][j];
	}
	cout << ans;
}

星期三:

背包dp第二题:                        cf传送门

思路:dp【i】【j】表示考虑到第 i 个,放了 j 个数的最大价值

转移:dp【i】【j】从dp【i】【j-1】或dp【i-1】【j】转移过来

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
ll p,q,r;
int a[N];
ll dp[N][4];
void solve(){
	cin >> n >> p >> q >> r;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		dp[i][1]=dp[i][2]=dp[i][3]=-1e18;
	}
	dp[1][1]=p*a[1];
	dp[1][2]=(p+q)*a[1];
	dp[1][3]=(p+q+r)*a[1];
	for(int i=2;i<=n;i++){
		dp[i][1]=max(dp[i-1][1],p*a[i]);
		dp[i][2]=max(dp[i][1]+q*a[i],dp[i-1][2]);
		dp[i][3]=max(dp[i][2]+r*a[i],dp[i-1][3]);
	}
	cout << dp[n][3];
}

一天vp了两场cf global round,越vp越对6号晚上没信心,上午那场卡A,晚上这场卡B

A就不说了,纯属我脑子不好使,贴下第二场的B                 cf传送门

思路:答案为最大值 除以 所有数的gcd,有点赛时猜结论的风格

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int a[N],gc;
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
void solve(){
	cin >> n;
	gc=0;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		gc=gcd(a[i],gc);
	}
	cout << a[n]/gc << "\n";
}

就酱紫,好好休息,清明节假期猛猛练

星期四:

cf global round 23,B题越看越不想看,跳了,补C                       cf传送门

思路:比较简单,因为操作很强,逆序对必能都填上

贴这题是因为使用vector时又忘了判是否为空了

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int p[N];
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++) cin >> p[i];
	vector<PII>ve;
	for(int i=1;i<n;i++)
		if(p[i]>p[i+1])
			ve.push_back({p[i]-p[i+1],i+1});
	sort(ve.begin(),ve.end(),greater<PII>());
	if(ve.empty()){
		for(int i=1;i<=n;i++) cout << "1 ";
		cout << "\n";
		return ;
	}
	for(int i=1;i<=n;i++){
		if(ve.size() && i>=ve.back().first) cout << ve.back().second << " ",ve.pop_back();
		else cout << 1 << " ";
	}
	cout << "\n";
}

接着补D                                           cf传送门

思路:树上dp,贪心的想每条路径一定会从根节点到子节点

假设父节点有c条路径,sz个子节点,根据题意,每个子节点分配的路径数为c/sz(向下取整 或 c/sz(向上取整,算出子节点分配路径为向上和向下取整后的值,根据其差值排序,前c %sz个子节点向上取整

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int s[N],k;
vector<int>ve[N];
ll dp[N][2];
void dfs(int x,int c){            //节点为x,有c条路径在此节点
	dp[x][0]=1ll*s[x]*c;
	dp[x][1]=1ll*s[x]*(c+1);
	if(ve[x].empty()) return ;
	int sz=ve[x].size();
	vector<int>tmp;
	for(auto i:ve[x])
		dfs(i,c/sz),tmp.push_back(i);
	for(auto i:tmp) dp[i][1]-=dp[i][0];
	sort(tmp.begin(),tmp.end(),[&](int a,int b){
		return dp[a][1]>dp[b][1];
	});
	int lef=c%sz;
	for(int i=0,tsz=tmp.size();i<tsz;i++){
		dp[x][0]+=dp[tmp[i]][0];
		if(i<lef) dp[x][0]+=dp[tmp[i]][1];
		dp[x][1]+=dp[tmp[i]][0];
		if(i<=lef) dp[x][1]+=dp[tmp[i]][1];   //父节点向上取整也可以给子节点多分配一个
	}
}
void solve(){
	cin >> n >> k;
	for(int i=1;i<=n;i++) ve[i].clear();
	for(int i=2;i<=n;i++){
		int p; cin >> p;
		ve[p].push_back(i);
	}
	for(int i=1;i<=n;i++) cin >> s[i];
	dfs(1,k);
	cout << dp[1][0] << "\n";
}

cf global round 24 C                                    cf传送门

思路:把数分为两个集合,一个集合为大数,另一个存小数,两集合间任意建边,边数为sum1 * sum2,遍历一遍大数小数的界限,记录最大答案即可

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int a[N];
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++) cin >> a[i];
	sort(a+1,a+n+1);
	if(a[1]==a[n]){
		cout << n/2 << "\n";
		return ;
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		while(a[i]==a[i+1]) i++;
		ll sum1=i,sum2=n-i;
		ans=max(sum1*sum2,ans);
	}
	cout << ans << "\n";
}

星期五:

下午蓝桥训练赛,被dp拿下了,准备补题

晚上牛客小白月赛,做到了E, STL题,还不错

dp题单数位dp第三题:                              cf传送门

思路:假设先对n作一步处理, 结果为1000以内的数,把1000以内的数到1的操作数预处理出来

然后开始填数,保证其小于等于n,填好后即为未操作过的数,1的数量cnt1即为操作一步后的数,若cnt1到1的操作数为k-1,即符合条件

特判,k为0,ans为1,k为1时,判定条件为cnt【cnt1】==0,1也会被算进答案里,故答案减1

代码如下:

ll n;
string s;
int k;
int num[1010],cnt[1010];
ll dp[1010][1010][2];
int getc(int x){
	int res=0;
	while(x!=1) x=__builtin_popcount(x),res++;
	return res;
}
int dfs(int lef,int cnt1,int if1){       //还剩lef长度没填,目前填了cnt1个1,是否为上界状态
	if(!lef){
		if(!cnt1) return 0;
		return cnt[cnt1]==k-1;         //一步操作为cnt1,再k-1步操作为1,则合法
	}
	if(dp[lef][cnt1][if1]!=-1)           //记忆化处理
		return dp[lef][cnt1][if1];
	ll res=0;
	if(if1){                             //为上界状态
		if(num[lef]){                    
			res+=dfs(lef-1,cnt1+1,1),res%=mod;   //填1,保持上界状态
			res+=dfs(lef-1,cnt1,0),res%=mod;
		}else res+=dfs(lef-1,cnt1,1),res%=mod;   //这位为0,就只能填0
	}else{                                      //否则填0或1均可
		res+=dfs(lef-1,cnt1+1,0),res%=mod;
		res+=dfs(lef-1,cnt1,0),res%=mod;
		
	}
	return dp[lef][cnt1][if1]=res;             //记忆化处理
}
void solve(){
	cin >> s >> k;
	if(!k){cout << 1; return ;}
	for(int i=1;i<=1000;i++)                  //预处理操作数
		cnt[i]=getc(i);
	int sz=s.size();
	for(int i=1;i<=sz;i++) num[i]=s[sz-i]-'0';
	memset(dp,-1,sizeof dp);
	ll ans=dfs(sz,0,1);
	if(k==1) ans--;
	cout << ans;
}

星期六:

蓝桥杯补题:

思路:前缀和预处理

(a【j】- a【i-1】)%k==0,可以转化为a【j】%k==a【i-1】%k

代码如下:

ll n;
int sum,k;
map<int,int>mp;
void solve(){
	cin >> n >> k;
	ll ans=0;
	mp[0]=1;
	for(int i=1;i<=n;i++){
		int x; cin >> x;
		sum+=x,sum%=k;
		ans+=mp[sum];
		mp[sum]++;
	}
	cout << ans;
}

晚上abc和cf global round25,都止步于D

星期天:

思路:用前缀异或和能优化到n^2,继续优化则考虑拆位

           Sl-1 ^ Sr从二进制位上看,两数在 i 位上相异,就能对答案产生1<< i 的贡献,任意的一个0和一个1就能产生这样的区间,所以按位统计前缀和中的0和1的数量,能在 i 位数上产生sum0*sum1个区间,对答案产生 1<< i * sum0*sum1 的贡献

这里还有一个注意的点,在统计前缀和第 i 位0 1数量时,我使 a【j】 & 1<< i ,这样是错误的,因为如果a【j】第 i 位为0,上式结果还是0,但若为1,上式结果会是1<< i ,即产生了越界,并没有被统计到1的数量里,在布尔式判断对错时,a【j】& 1<< i 和 a【j】>> i & 1 效果是相同的,但这种情况就并非如此了,需注意

代码如下:

const int N=2e6+10,M=210;
const int mod=1e9+7;
ll n;
int a[N];
int c[22][2];
void solve(){
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		a[i]^=a[i-1];
	}
	for(int i=0;i<=20;i++)
		for(int j=0;j<=n;j++)
			c[i][a[j]>>i&1]++;   //a[j]&1<<i结果为1<<i而并非1
	ll ans=0;
	for(int i=0;i<=20;i++)
		ans+=(1ll<<i)*c[i][0]*c[i][1];
	cout << ans;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1576265.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenAI Sora:浅析文生视频模型Sora以及技术原理简介

一、Sora是什么&#xff1f; Sora官方链接&#xff1a;https://openai.com/sora 视频模型领头羊Runway Gen 2、Pika等AI视频工具&#xff0c;都还在突破几秒内的连贯性&#xff0c;而OpenAI&#xff0c;已经达到了史诗级的纪录。 OpenAI&#xff0c;永远快别人一步&#xff0…

Android 11属性系统初始化流程

在init进程启动的第二阶段&#xff0c;调用PropertyInit 对属性系统进行初始化 int SecondStageMain(int argc, char** argv) {//省略PropertyInit();//省略 }PropertyInit函数在system\core\init\property_service.cpp 中实现 void PropertyInit() {//省略mkdir("/dev/…

《云原生安全攻防》-- 云原生应用风险分析

为了满足每位朋友的学习需求&#xff0c;并且支持课程的持续更新&#xff0c;本系列课程提供了免费版和付费视频版两种方式来提供课程内容。我们会持续更新课程内容&#xff0c;以确保内容的度和实用性。 在本节课程中&#xff0c;我们将一起探讨云原生应用在新的架构模式下可能…

模块化——如何导入模块?(内置模块与自定义模块)

在Node.js中&#xff0c;要导入另一个模块&#xff0c;我们可以使用require函数。这个函数接受一个文件路径参数&#xff0c;并返回导入的模块。 一、require使用注意事项&#xff1a; (1)自己创建的模块&#xff0c;导入时建议写相对路径&#xff0c;不能省略./和../ //我把…

Struts2:Action类的写法,推荐使用继承ActionSupport类的方法

文章目录 方法一&#xff1a;Action类是一个POJO类&#xff08;简单的Java类&#xff09;ActionDemo2.javastruts_demo2.xmlstruts.xml运行结果其他strutsz_demo1.xml 方法二&#xff1a;实现一个Action的接口ActionDemo2_2.javastruts_demo2.xml运行结果 推荐&#xff01;&…

基于视频监管与AI智能识别技术的水利河道综合治理解决方案

一、方案介绍 TSINGSEE青犀视频水利河道综合治理解决方案是依托视频AI智能分析技术&#xff0c;利用水质/水文等传感器、高清摄像机、水利球、无人机、无人船等感知设备实时采集数据&#xff0c;并与视频能力进行联动&#xff0c;达到智能预警的目的。 TSINGSEE青犀方案以信息…

【单源最短路 图论】882. 细分图中的可到达节点

作者推荐 视频算法专题 本文涉及知识点 单源最短路 图论 LeetCode 882. 细分图中的可到达节点 给你一个无向图&#xff08;原始图&#xff09;&#xff0c;图中有 n 个节点&#xff0c;编号从 0 到 n - 1 。你决定将图中的每条边 细分 为一条节点链&#xff0c;每条边之间…

4月7号总结

java学习 一.正则表达式 定义&#xff1a;正则表达式是一种用于描述字符串模式的表达式&#xff0c;通常被用于文本搜索、匹配和替换。它是一种强大的工具&#xff0c;可以在文本处理和文本分析中进行复杂的匹配和操作。 通过字符串引用里面的方法matches&#xff0c;然后执行…

jupyter python paramiko 网络系统运维

概述 通过使用jupyter进行网络运维的相关测试 设备为H3C 联通性测试 import paramiko import time import getpass import re import os import datetimeusername "*****" password "*****" ip "10.32.**.**"ssh_client paramiko.SSHCli…

相机标定——四个坐标系介绍

世界坐标系(Xw,Yw,Zw) 世界坐标系是一个用于描述和定位三维空间中物体位置的坐标系&#xff0c;通常反映真实世界下物体的位置和方向。它是一个惯性坐标系&#xff0c;被用作整个场景或系统的参考框架。在很多情况下&#xff0c;世界坐标系被认为是固定不变的&#xff0c;即它…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之四 简单视频倒放效果 一、简单介绍 二、简单视频倒放效果实现原理 三、简单视频倒放效果案例实现…

C++搭建深度学习的推理框架

我们的目的是:借助C++搭建一个类似于pytorch,tensorflow的深度学习框架,对标pytorch,tensorflow实现对应的功能。由于本人能力有限,下面本人将借助C++搭建一个简单的全连接神经网络,并且尝试解释里面的算子定义和计算图构建。 算子定义 回顾pytorch里面搭建的全连接神经网…

探索未来游戏:生成式人工智能AI如何重塑你的游戏世界?

生成式人工智能&#xff08;Generative AI&#xff09;正以前所未有的速度改变着各行各业的运作模式。其中&#xff0c;游戏产业作为科技应用的前沿阵地&#xff0c;正经历着前所未有的变革。本文将探讨生成式人工智能如何重塑游戏产业&#xff0c;以及这一变革背后的深远影响。…

Sora是什么?Sora怎么使用?Sora最新案例视频以及常见问题答疑

Sora 是什么&#xff1f; 2024年2月16日&#xff0c;OpenAI 在其官网上面正式宣布推出文本生成视频的大模型Sora 这样说吧给你一段话&#xff0c; 让你写一篇800字的论文&#xff0c;你的理解很可能都有偏差&#xff0c;那么作为OpenAi要做文生视频到底有多难&#xff0c;下面…

Linux设备深探:桥接硬件与软件的秘密通道

在Linux的世界里&#xff0c;"设备"这个词汇比你想象的要丰富和多彩得多。让我们一起来探索Linux设备的奥秘&#xff0c;理解它们是如何在Linux操作系统中发挥作用的。&#x1f427;✨ 1. 什么是Linux设备&#xff1f; 在Linux中&#xff0c;设备被看作是一种特殊的…

Day01-SHELL自动化编程-变量与特殊变量

Day01-SHELL自动化编程-变量与特殊变量 1.编程概述2.课程内容3.Shell编程语言必知必会4.编程语言分类&#xff08;按照执行方式&#xff09;-了解5.编程环境准备6.Shell脚本执行方式6.1概述6.2详解6.2.1 sh或bash6.2.1 .或source6.2.3 相对或绝对路径6.2.4 使用重定向符号执行脚…

iOS 17.5系统或可识别并禁用未知跟踪器,苹果Find My技术应用越来越合理

苹果公司去年与谷歌合作&#xff0c;宣布将制定新的行业标准来解决人们日益关注的跟踪器隐私问题。苹果计划在即将发布的 iOS 17.5 系统中加入这项提升用户隐私保护的新功能。 科技网站 9to5Mac 在苹果发布的 iOS 17.5 开发者测试版内部代码中发现了这项反跟踪功能的蛛丝马迹…

Spring源码解析-容器基本实现

spring源码解析 整体架构 defaultListableBeanFactory xmlBeanDefinitionReader 创建XmlBeanFactory 对资源文件进行加载–Resource 利用LoadBeandefinitions(resource)方法加载配置中的bean loadBeandefinitions加载步骤 doLoadBeanDefinition xml配置模式 validationMode 获…

海外媒体宣发,穿透与世界的交流 - “保姆级”教程 - 大舍传媒

1. 引言 在当今高度信息化的世界&#xff0c;境外媒体宣发已经成为企业、品牌和政府机构推广自身形象、扩大影响力的重要手段。如何在国际舞台上有效传播信息&#xff0c;提高国际知名度&#xff0c;成为了许多组织面临的重要课题。大舍传媒凭借多年的境外媒体宣发经验&#x…

数据恢复与数据取证的便携工具:PC-3000 Portable III

天津鸿萌科贸发展有限公司从事数据安全业务20余年&#xff0c;在数据恢复、数据取证、数据备份等领域有丰富的案例经验、前沿专业技术及良好的行业口碑。同时&#xff0c;公司面向取证机构及数据恢复同行&#xff0c;提供实验室建设方案&#xff0c;包含数据恢复与数据取证硬件…