24.4.7周报

星期一:

再学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而并非1ll ans=0;for(int i=0;i<=20;i++)ans+=(1ll<<i)*c[i][0]*c[i][1];cout << ans;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《价值》-张磊-高瓴资本-5-投资是一场修行;坚持第一性原理;避开陷阱;信誉就是生命

第五章&#xff1a;价值投资者的自我修养 价值投资不是投资者之间的零和游戏&#xff0c;而是共同把蛋糕做大的正和游戏。 从事投资的过程中&#xff0c;我渐渐发觉&#xff0c;投资 一方面是对真理的探寻&#xff0c;探索外部世界&#xff1b;另一方面是谋求心灵的宁静&#x…

Mysql的物理文件

1.Windows下面的配置文件是&#xff1a;my.ini [mysql] default-character-setutf8[mysqld] port3306 default_authentication_pluginmysql_native_password basedirE:/phpStudy/phpstudy_pro/Extensions/MySQL8.0.12/ datadirE:/phpStudy/phpstudy_pro/Extensions/MySQL8.0.1…

ES学习笔记01

1.ES安装 下载地址&#xff1a; es官网下载 这里使用的是7.8.0的版本信息 下载完成后解压即可完成安装 2.启动运行 点击bin目录下的elasticsearch.bat文件即可启动 在浏览器中输入localhost:9200显示如下&#xff1a; 在路径中加入对应访问后缀即可访问对应信息 如&#…

leetcode - 678. Valid Parenthesis String

Description Given a string s containing only three types of characters: ‘(’, ‘)’ and ‘*’, return true if s is valid. The following rules define a valid string: Any left parenthesis ( must have a corresponding right parenthesis ). Any right parenth…

Linux云计算之Linux基础3——Linux系统基础2

1、终端 终端(terminal)&#xff1a;人和系统交互的必要设备&#xff0c;人机交互最后一个界面&#xff08;包含独立的输入输出设备&#xff09; 物理终端(console)&#xff1a;直接接入本机器的键盘设备和显示器虚拟终端(tty)&#xff1a;通过软件方式虚拟实现的终端。它可以…

如何理解图像处理领域的病态问题(ill-posed problem)

ill-posed problem&#xff0c;我们可以理解为病态问题或者不适定问题。在本文中&#xff0c;统一成为不适定问题。 在讨论不适定问题&#xff08;ill-posed problem&#xff09;之前&#xff0c;我们先来看一下什么叫适定性问题&#xff08;well-posed problem&#xff09;。…

QT C++(QT对象树与内存泄漏管理,QT中文乱码问题)

文章目录 1. QT对象树与内存泄漏2. QT中文乱码 1. QT对象树与内存泄漏 #include "widget.h" #include "ui_widget.h" #include <QLabel>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//通过代码构…

uniapp-设置UrlSchemes从外部浏览器H5打开app

需求&#xff1a;外部浏览器H5页面&#xff0c;跳转到uniapp开发的原生app内部。 1、uniapp内部的配置&#xff1a; &#xff08;1&#xff09;打开manifest->App常用其他设置&#xff0c;如下&#xff0c;按照提示输入您要设置的urlSchemes&#xff1a; &#xff08;2&am…

提取COCO数据集中特定的类—vehicle 4类

提取COCO数据集中特定的类—vehicle 4类 1 安装pycocotools2 下载COCO数据集3 提取特定的类别4 多类标签合并 1 安装pycocotools pycocotools github地址 pip install githttps://github.com/philferriere/cocoapi.git#subdirectoryPythonAPI2 下载COCO数据集 COCO官网下载2…

【Java多线程(4)】案例:设计模式

目录 一、什么是设计模式&#xff1f; 二、单例模式 1. 饿汉模式 2. 懒汉模式 懒汉模式-第一次改进 懒汉模式-第二次改进 懒汉模式-第三次改进 一、什么是设计模式&#xff1f; 设计模式是针对软件设计中常见问题的通用解决方案。它们提供了一种被广泛接受的方法来解决…

GEE数据集—— 2020 年全球森林覆盖图10 米的空间分辨率

简介 欧洲共同体联合研究中心的全球森林覆盖图以 10 米的空间分辨率提供了 2020 年森林存在和不存在的明确空间表示。 2020 年是欧盟 "关于在欧盟市场上提供和从欧盟出口与毁林和森林退化相关的某些商品和产品 "的条例&#xff08;EUDR&#xff0c;条例&#xff08…

vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户

1.后端返回的json数据结构为&#xff1a; {"message":"下载失败&#xff0c;下载文件不存在&#xff0c;请联系管理员处理&#xff01;","code":500} 2.vue 请求后台接口返回的 Blob数据 3.问题出现的原因是&#xff0c;正常其他数据列表接口&…