一、命令行安装 compression-webpack-plugin npm i -D compression-webpack-plugin 二、在 vue.config.js 里面配置 compression-webpack-plugin,如果没有vue.config.js则在项目根目录创建vue.config.js "use strict"; const path = require("path"); const CompressionWebpackPlugin = require("compression-webpack-plugin"); const productionGzipExtensions = ["js", "css"]; function resolve(dir) { return path.join(__dirname, dir); } const name = "品牌联盟"; module.exports = { lintOnSave: process.env.NODE_ENV === "development", configureWebpack: { name: name, resolve: { alias: { "@": resolve("src"), "@i": resolve("src/api"), "@c": resolve("src/components"), "@v": resolve("src/pages"), "@s": resolve("src/static"), "@u": resolve("src/utils") } }, plugins: [ new CompressionWebpackPlugin({ filename: "
模型剪枝简单理解 1 概念2 引入3 过程4 权重筛选5 举例 最近在学习模型剪枝的方法,尝试了TF官方的模型剪枝工具tfmot,这里对目前学习到的模型剪枝做简单总结。学习过程中参考了Sayak Paul的一篇文章Scooping into Model Pruning in Deep Learning
1 概念 剪枝是将神经网络中的不重要参数置为0
2 引入 考虑函数 f(x) = x + 5x2,系数分别为1和5。下图可以看到,当第一个参数发生变化时,函数的输出不会发生太大变化。故舍弃这些系数并不会真正改变函数的行为。
同理可以应用到神经网络,在梯度下降的优化过程中,并不是所有的权重都使用相同的梯度幅度进行更新,某些权重比其他权重的梯度幅度更大,优化器认为这些权重很重要,可以最大程度地减少训练。
3 过程 1)训练一个大的过参数化模型
2)根据某个标准修剪训练好的模型
3)微调修剪后的模型,以恢复损失的性能
4 权重筛选 可以指定一个阈值,并且所有大小超过该阈值的权重都将被认为是重要的。
1) 阈值可以是整个网络内部最低的权重值
2) 阈值可以是网络内部各层本身的权重值。在这种情况下,重要的权重会逐层过滤掉。
5 举例 在基于幅度的修剪中,将权重大小视为修剪的标准。假设输入层中有3个神经元,接受形状为(1,2)。
我们想要裁剪掉权重矩阵中70%的参数,代码实现如下:
# 复制内核权重并获取列级L2范数的排名索引 kernel_weights = np.copy(k_weights) ind = np.argsort(np.linalg.norm(kernel_weights, axis=0)) # 定义索引将被置为0的数量 sparsity_percentage = 0.7 cutoff = int(len(ind)*sparsity_percentage) # 将2D kernel权重矩阵中的索引设置为0 sparse_cutoff_inds = ind[0:cutoff] kernel_weights[:,sparse_cutoff_inds] = 0. 权重学习后发生的变换如下图所示
引 今天进行了招行提前批的视频面试,写编程题的时候完全没法下手,我觉得很大一部分原因是平时刷题太少,而且记录总结太少,于是在这里做一个刷题记录,希望等到秋招能找到理想的工作。
以今天遇到的面试题开始吧…
题目:找到大于一个正整数n的最小2的次幂数 int solve (int num) { int base = INT_MIN; if (num >= base) { base = num; base |= (base >> 1); //把base最高位的下一位置1 base |= (base >> 2); base |= (base >> 4); base |= (base >> 8); base |= (base >> 16); base++; if (base < 0) base >>= 1; } return base; }
针对webkit内核的浏览器(谷歌、ie、Safari等): 实现效果:
(利用border实现边距)
使用伪类改变滚动条样式
1. ::-webkit-scrollbar 滚动条整体
2. ::-webkit-scrollbar-thumb 滚动条的方块
3. ::-webkit-scrollbar-track 滚动条的轨道
4. ::-webkit-scrollbar-button 滚动条的两端按钮
5. ::-webkit-scrollbar-track-piece 内层轨道,滚动条中间部分
6. ::-webkit-scrollbar-corner 边角,即垂直滚动条和水平滚动条相交的地方
/*修改滚动条样式*/ div::-webkit-scrollbar { width: 15px; height: 15px; } div::-webkit-scrollbar-track { background: #f1f1f1; } div::-webkit-scrollbar-thumb { background: #ddd; border-radius: 7px; height: 50px; border: 4px solid #f1f1f1; } div::-webkit-scrollbar-track-piece { width: 10px; } div::-webkit-scrollbar-thumb:hover { background: #dddddd; } div::-webkit-scrollbar-corner { background: #dddddd; } 对于火狐浏览器 首先踩了一个坑:flex布局下面overflow不生效,网上找了资料看,发现也不能解决,所以最后直接改变实现的思路
既然flex和overflow不能写一起,那我就把这个拆开来写
本来的样式:
.xxx { flex-direction: column-reverse; display: flex; overflow-y: auto; height: vw(480); width: vw(192); } 修改成:
1、宏定义的一般形式为:
宏定义: #define 标识符 常量 //注意:没有分号 终止宏: #undef 标识符 提醒:
#define和#include一样,均以"#“开头。凡是以”#"开头的均为预处理命令,其后边不加分号。
为了讲标识符和变量名区分开来,习惯上标识符全部用大写字母。
2、 为什么要使用宏定义或者说有何优点?
2.1 最大的好处就是便于程序的修改。使用宏定义代替一个程序中常用的变量,当需要修改该变量时,只需修改其宏定义即可,方便代码的修改和维护。
2.2 提高代码的可读性。
3、程序举例
1 #include<stdio.h> 2 #define pi 3.14 3 int main() 4 { 5 float r=1.0; 6 float area=pi*r*r; 7 printf("the area of the circle is %f",area); 8 return 0; 9 } 结果:
the area of the circle is 3.140000
Windows身份验证提供程序: 提供有关如何将 Windows 身份验证与 Microsoft Internet 信息服务 (IIS) 身份验证结合使用来确保 ASP.NET 应用程序安全的信息。
Forms 身份验证提供程序 : 提供有关如何使用您自己的代码创建应用程序特定的登录窗体并执行身份验证的信息。使用 Forms 身份验证的一种简便方法是使用 ASP.NET 成员资格和 ASP.NET 登录控件,它们一起提供了一种只需少量或无需代码就可以收集、验证和管理用户凭据的方法。
Passport 身份验证提供程序 : 提供有关由 Microsoft 提供的集中身份验证服务的信息,该服务为成员站点提供单一登录和核心配置
**C 库函数 - strstr()
C 库函数 char *strstr(const char *haystack, const char *needle) 在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’
const char haystack[20] = “00000B”;
const char needle[10] = “000B”;
char *ret;
ret = strstr(haystack, needle);
printf(“子字符串是: %s\n”, ret);**
本文总结CVPR 2020 中所有与图像和视频检索(Image and Video Retrieval)相关论文,总计 16 篇。
图像和视频检索常见于搜索引擎、商品服饰搜索等应用场景,另外为进行高效检索,该领域往往会将图像或者视频的特征通过哈希算法映射到二值空间,使用汉明距比较相似度,所以哈希算法也是该领域重要研究内容。
这部分论文方向比较分散,包括:
半监督图像检索 1篇,
组合查询图像检索 2篇
对抗图像检索 1篇
服饰检索 2篇
基于草图的图像检索 2篇
跨模态图像文本检索 2篇
跨模态视频文本检索 1篇
域适应图像检索 1篇
哈希算法 3篇
新数据集 1篇。
最有意思的、可能也是难度最大的是把文本和图像结合起来的组合查询图像检索和跨模态图像/视频-文本检索。
绝大部分论文代码开源或者即将开源,代码地址也一并附上了。
大家可以在:
http://openaccess.thecvf.com/CVPR2020.py
按照题目下载这些论文。
如果想要下载所有CVPR 2020论文,请点击这里:
CVPR 2020 论文全面开放下载,含主会和workshop
半监督图像检索
半监督图像检索
[1].Generalized Product Quantization Network for Semi-Supervised Image Retrieval
作者 | Young Kyun Jang, Nam Ik Cho
单位 | 韩国首尔大学
代码 | https://github.com/youngkyunJang/GPQ
组合查询图像检索
给定一幅查询图像和相关文本,检索出满足文本描述的与查询图像相似的图像(CVPR 2019新提出的检索新模式)
[2].Composed Query Image Retrieval Using Locally Bounded Features
栈的主要目的用来存储数据,很少需要在栈中运行代码,因此,大多数程序不需要可执行的程序栈,在一些体系架构中(包括x86),可以在硬件程序面上将一段内存区域标记为不可执行。在Ubuntu系统中,如果使用gcc编译程序,可以让gcc生成一个特殊的二进制文件,这个二进制文件头部有一个比特位,表示是否将栈设置为不可执行,当程序被加载执行时,操作系统首先为程序分配内存,然后检查该比特位,如果它被置位,那么栈的内存区域将被标记为不可执行。#include <string.h> const char code[] = "\x31\xc0" /* xorl %eax,%eax */ "\x50" /* pushl %eax */ "\x68""//sh" /* pushl $0x68732f2f */ "\x68""/bin" /* pushl $0x6e69622f */ "\x89\xe3" /* movl %esp,%ebx */ "\x50" /* pushl %eax */ "\x53" /* pushl %ebx */ "\x89\xe1" /* movl %esp,%ecx */ "\x99" /* cdq */ "\xb0\x0b" /* movb $0x0b,%al */ "\xcd\x80" /* int $0x80 */ ; int main(int argc, char **argv) { char buf[sizeof(code)]; strcpy(buf, code); ((void(*)( ))buf)( ); } 上述代码首先将一段shellcode放入栈中的缓冲区,然后将缓冲区转换为函数,,接着调用这个函数。运行[07/07/20]seed@VM:~/code$ gcc -z execstack shellcode.
今天为了写一个脚本,打开了最顺手的 jupyter notebook,但是出现了这种情况:在 Anaconda Prompt 中显示正常(如下图)
但是在浏览器(我用的是Chrome83.0.4103.116)中弹出来的确是一个空白页(如下图)
我以为是配置主题、字体、默认浏览器和自己常用模块的时候改错了变量,所以我选择了最简单粗暴行之有效的方法:重装!
但是从 FirstTimes 到 NineTimes 都没能解决这一问题,我就意识到不是修改上述所说的东西出了问题,而是 jupyter notebook本身的问题或者是浏览器的问题,我选择相信第一种原因,因为我往常用的都是 Chrome,并没有出现过什么问题,于是卸载 jupyter notebook 然后再 conda install jupyter notebook! 问题依旧存在!!!这就是浏览器的问题了!
我换了系统自带的 Edge 浏览器,完美运行!如下图:
虽然不知道为什么 Chrome 出现了这样的问题,但是能解决这两天的困扰也是值得记录一下的!加油!明天会更好!
解析:
我们将书分为三种
第一种:只有Alice 喜欢
第二种:只有Bob 喜欢
第三种:Alice和Bob都喜欢
我们只需贪心地单独取就是第一种和第二种分别取。如果数量不够k个,那么我们就要从第三种里面开始取。
等取够k个的时候,我们再从第三种里面去找最优的情况,来代替单独取,使得答案最小
#include<bits/stdc++.h> using namespace std; const int N=2e5+1000; typedef long long ll; ll a[N],b[N],c[N]; int n,k,t; int cnt0,cnt1,cnt2; int main() { ll ans=0; cin>>n>>k; for(int i=1,f,f1;i<=n;i++) { cin>>t>>f>>f1; if(f==1&&f1==1) c[++cnt2]=t; else if(f==1) a[++cnt0]=t; else if(f1==1) b[++cnt1]=t; } sort(a+1,a+1+cnt0); sort(b+1,b+1+cnt1); sort(c+1,c+1+cnt2); for(int i=1;i<=k;i++) ans+=(a[i]+b[i]);//单独取 cnt0=min(cnt0,k);cnt1=min(cnt1,k); int l=cnt0,r=cnt1; int m=min(l,r); int s=1; if(m<k) //不够k个,从第三种里面取 { if(k-m>cnt2) { cout<<-1<<endl; return 0; } s=k-m+1; for(int i=1;i<=k-m;i++) { if(l<k&&r<k) l++,r++,ans+=c[i]; else if(l<k) { l++; if(cnt1) ans=ans-b[cnt1--]+c[i]; } else if(r<k) { r++; if(cnt0) ans=ans-a[cnt0--]+c[i]; } } } for(int i=s;i<=cnt2;i++) //取完k个,从第三种挑选最优方案来代替单独取 { ll sum=a[cnt0]+b[cnt1]; if(sum>c[i]) { ans=ans-sum+c[i]; if(cnt1) cnt1--; if(cnt0) cnt0--; } } cout<<ans<<endl; }
ubuntu16.04的HDMI没有输出不能外接显示器 原因解决办法显卡驱动安装检查自己的显卡型号下载nvidia驱动准备工作开始安装结束工作 如果以上的步骤下来还不成功 结束 原因 ubuntu系统电脑如果有两个显卡:独显和核显,就会出现HDMI没有信号,因为电脑默认使用核显,而HDMI的输出是由独显给的,所以会出现HDMI没有信号的情况。
解决办法 安装自己的独显驱动。
显卡驱动安装 检查自己的显卡型号 方法一、 最不费脑子的办法:重启进入windows,设备管理器直接看显卡型号,或者下载鲁大师硬件检测会有显卡型号。
方法二:lspci | grep -i vga会出现一个16进制的数字
选有nvidia的那个就是独显(我的是2191),把这个16进制数字粘贴到PCI devices(网址进去较慢,耐心ing)可以查询到显卡的型号。
下载nvidia驱动 下载驱动网址,查询到之后选择一个版本下载。
准备工作 禁用nouveau
sudo gedit /etc/modprobe.d/blacklist.conf 在打开的文件中加入
blacklist nouveau options nouveau modeset=0 更新系统
sudo update-initramfs -u 重启
sudo reboot 验证是否禁用nouveau,若系统没有任何输出则禁用成功。
lsmod | grep nouveau 开始安装 将下载的.run文件放在home文件夹下以便之后使用(一定要做)。
在ubuntu下ctrl+alt+f1进入命令行界面,在命令行界面ctrl+alt+f7退出命令行界面。(以防进去之后不知道怎么出来) 之后的步骤最好先用手机拍照再进行
sudo service lightdm stop //关闭图形界面
进入命令行界面ctrl+alt+f1
输入自己的用户名,回车
输入自己的登录密码,回车
sudo apt-get remove nvidia-* //卸载原有驱动
sudo chmod 777 NVIDIA-Linux-x86_64-430.64.run //将驱动转换成可执行文件
NVIDIA-Linux-x86_64-430.64.run是我的驱动文件,这个要改成自己的
sudo ./NVIDIA-Linux-x86_64-430.64.run -no-nouveau-check -no-opengl-files//输全了
矩阵快速幂 要点习题2019牛客第五场 B. generator 1 (矩阵快速幂)递推例题Matrix Power Series POJ - 3233HDU - 2276 Kiki & Little Kiki 2HDU - 5015 233 MatrixCF1182 E. Product Oriented Recurrence 要点 两个矩阵做乘法的时候,累积到一个全 0 的矩阵上。在做快速幂的时候需要设为单位矩阵,相当于 1。矩阵中出现负数,记得要及时取正数。 习题 2019牛客第五场 B. generator 1 (矩阵快速幂) 链接:https://ac.nowcoder.com/acm/contest/885/B
思路:矩阵快速幂,先找到转移矩阵
[ a b 1 0 ] × [ f n − 1 f n − 2 ] = [ f n f n − 1 ] \begin{bmatrix} a & b \\ 1 & 0 \end{bmatrix} \times \begin{bmatrix} f_{n-1}\\ f_{n-2} \end{bmatrix}= \begin{bmatrix} f_{n}\\ f_{n-1} \end{bmatrix} [a1b0]×[fn−1fn−2]=[fnfn−1]
一、自回归模型的定义 将预测对象按照时间顺序排列起来,构成一个所谓的时间序列,从所构成的一组时间序列的变化规律,推断今后变化的可能性及变化趋势、变化规律,就是时间序列预测法。
时间序列模型其实也是一种回归模型,其基于的原理是,一方面承认事物发展的延续性,运用过去时间序列的数据统计分析就能推测事物的发展趋势;另一方面又充分考虑到偶然因素影响而产生的随机性,为了消除随机波动的影响,利用历史数据,进行统计分析,并对数据进行适合的处理,进行趋势预测。
自回归模型是用自身做回归变量的过程,即利用前期若干时刻的随机变量的线性组合来描述以后某时刻随机变量的线性回归模型,它是时间序列中的一个常见形式。
二、自回归模型的表现形式 考虑一个时间序列的 y1,y2,…,yn,p 阶自回归模型(简称为AR§)表明序列中yt是前 p 个序列的线性组合及误差项的函数,一般形式的数据模型为:
y t = Φ 0 + Φ 1 y t − 1 + Φ 2 y t − 2 + … + Φ p y t − p + ε t y_t = Φ_0+Φ_1y_{t-1}+Φ_2y_{t-2}+…+Φ_py_{t-p}+ε_t yt=Φ0+Φ1yt−1+Φ2yt−2+…+Φpyt−p+εt
其中,Φ0是常数项,Φ1,…,Φp 是模型参数,εt是具备均值为 0,方差为 σ 的白噪声(白噪声是指功率谱密度在整个频域内均匀分布的噪声)。
三、Matlab_AR模型阶数确定 有几种方法来确定。如 Shin 提出基于 SVD的方法,而 AIC和 FPE方法是目前应用最广 泛的方法。 若计算出的 AIC较小,例如小于 -20,则该误差可能对应于损失函数的 10-10级别, 则这时阶次可以看成是系统合适的阶次。
四、matlab 相关性分析 Pearson相关系数 考察两个事物(在数据里我们称之为变量)之间的相关程度,简单来说就是衡量两个数据集合是否在一条线上面。其计算公式为:
N表示变量取值的个数。
相关系数r的值介于–1与+1之间,即–1≤r≤+1。其性质如下:
假设来到阿里巴巴面试,面试官可能就会让你反转下二叉树镜像。请大家先思考下,怎么实现?
(1)命令式编程思维
一种实现方式是这样的:
Node invertTree(root){ if (root is null){ return null; } root.left = invertTree(root.right); root.right = invertTree(root.left); return root; } 我们首先判断节点是否为空,如果为空则直接抛出;然后翻转右树放置在左边;翻转左树放置在右边。
这其实是一种命令式编程方式,即我们把要做的事情,以步骤的形式描述出来,然后交给机器去执行。
这也正是命令式编程的理论模型——图灵机的特点。一条写满数据的纸带,一条根据纸带内容运动的机器,机器的每一步都需要在纸带上写出命令。
图灵机指的是一个抽象的机器,它有一条无限长的纸带,纸带分成了一个一个的小方格,每个方格有不同的颜色。有一个机器头在纸带上移来移去。机器头有一组内部状态,还有一些固定的程序。在每个时刻,机器头都要从当前纸带上读入一个方格信息(命令),然后结合自己的内部状态查找程序表,根据程序输出信息到纸带方格上,并转换自己的内部状态,然后进行移动。
(2)函数式编程思维
函数式思维提供了另一种思维途径——翻转二叉树,我们可以看做是要得到一颗和原来二叉树对称的新二叉树。这颗新二叉树的特点是每一个节点都递归地和原树相反。
Node invert(node){ if (node is null) { return null; } else { return new Tree(node.value, invert(node.right), invert(node.left)); } } 这段代码体现的思维是旧树到新树的映射。对一颗二叉树而言,它的镜像树就是左右节点递归镜像的树。
同样是翻转二叉树,但这段代码得到结果的方式和之前的命令编程模式有本质的差别:通过描述一个 旧树->新树 的映射,而不是描述「从旧树得到新树应该怎样做」来达到目的。
世界的两部分好像在照镜子,就称为镜像世界。
函数式编程思维:描述旧树到新树的映射关系。
命令式编程思维:描述从旧树得到新树应该怎样做。
数据批注(作为System。ComponentModel。DataAnnotations命名空间的一部分提供)是可以应用于类或类成员的属性,以指定类之间的关系,描述如何在UI中显示数据以及指定验证规则。 本文讨论数据注释,为什么有用,以及如何在我们的.NET Core应用程序中使用它们。 若要使用本文提供的代码示例,您应该在系统中安装Visual Studio 2019。 如果您还没有副本,则可以在此处下载Visual Studio 2019 。 [ 同样在InfoWorld上:隔离期间最好的免费编程课程 ] 在Visual Studio 2019中创建控制台应用程序项目 首先,让我们在Visual Studio中创建一个.NET Core Console Application项目。 假设系统中已安装Visual Studio 2019,请按照以下概述的步骤在Visual Studio中创建新的.NET Core控制台应用程序项目。 启动Visual Studio IDE。 点击“创建新项目”。 在“创建新项目”窗口中,从显示的模板列表中选择“控制台应用程序(.NET Core)”。 点击下一步。 在接下来显示的“配置新项目”窗口中,指定新项目的名称和位置。 单击创建。 这将在Visual Studio 2019中创建一个新的.NET Core控制台应用程序项目。在本文的后续部分中,我们将使用该项目来处理数据注释。 包括系统。 ComponentModel。 DataAnnotations名称空间 要使用本文给出的代码示例,您应该包括系统。 ComponentModel。 程序中的DataAnnotations命名空间。 请注意,属性用于指定类或属性上的元数据。 数据注释属性可以大致分为以下几类: 验证属性-用于对实体的属性实施验证规则 显示属性-用于指定应如何在用户界面中显示数据 建模属性-用于指定类之间存在的关系 C#中的数据注释属性类 System.ComponentModel.Annotations命名空间包含几个属性类,这些属性类可用于为您的实体类或数据控件定义元数据。 最常用的属性包括: 并发检查 键 最长长度 需要 字符串长度 时间戳记 C#中的数据注释示例 在我们之前创建的控制台应用程序中的Author.cs文件中创建以下类。 public class Author
{
[Required(ErrorMessage = "{0} is required"
ROS实战之重定位——NDT 目录安装方法绘制轨迹结果参考 目录 安装方法 拷贝到工作区,编译,运行,环境依赖同上一篇,Ubuntu16.04+ROS Kinetic+PCL+GTSAM,在运行前将要加载的点云地图放到map目录下,并命名为kaist02.pcd
cd ~/catkin_ws/src
git clone https://github.com/irapkaist/SC-LeGO-LOAM.git
cd …
catkin_make
source devel/setup.bash
roslaunch lego_loam run.launch
和上节一样,播放自己的数据集就可以啦,播放之前在rviz中先发布当前位姿,在起点画一个水平向左的箭头,一定要这样操作。
绘制轨迹 想在重定位结果中绘制出机器人的运动轨迹,需要添加一些代码,用的是nav_msgs/Path这个类型的消息来实现
在 [ 你的目录路径 ] /src/ndt_localizer/nodes/ndt.cpp中进行如上图修改,添加的代码是230,231,232,236行,同时要记得在ndt.h头文件中申明变量,如下图所示
ros::Publisher path_pub; 在的构造函数中定义变量,构造函数就是NdtLocalizer::NdtLocalizer(ros::NodeHandle &nh, ros::NodeHandle &private_nh):nh_(nh), private_nh_(private_nh), tf2_listener_(tf2_buffer_)
{……},定义如下
path_pub = nh_.advertise<nav_msgs::Path>("trajectory",1, true); 重新编译,运行即可
在rviz中订阅话题,ADD by Topic,选择path即可
结果 紫色的就是绘制出的机器人运动轨迹了
参考 https://github.com/AbangLZU/ndt_localizer
https://blog.csdn.net/u013834525/article/details/80447931?utm_source=blogkpcl0
This way
题意: 现在有两个人要一起读书,有n本书,他们要读正好m本,每本书有3个属性:
t:表示读完这本书要的时间,a:第一个人是否喜欢这本书,b:第二个人是否喜欢这本书。
让你构造一种方案使得他们读的书正好是m本,并且这些书中第一个人喜欢的书有>=k本,第二个人喜欢的书有>=k本,并且读书时间最少。
题解: 感觉最近做的题目都有点贪心的思想。并且这道题目 恶心到我了,我做了很久,一开始的想法错误到后来改正了想法之后慢慢debug。
但是这道题目就听听思路就好了,我的代码的话有点长,可能看完之后在重新想一遍会来的舒服一点。
但是时间复杂度还算可以,就一个排序是 O ( n l o g n ) O(nlogn) O(nlogn),其它是 O ( n ) O(n) O(n)的
那么首先可以知道,一旦(1,1)的数量定了,那么我们可以通过贪心的方法去做,也就是答案就定了。
那么我们如何在枚举(1,1)的数量的同时快速的得到答案?
假设我当前有这么多的(1,1),这么多的(0,1),还有这么多的(1,0)和(0,0)
我如果这些都是排好序的,那么我新增一个(1,1)的时候,是不是只需要将下面3中情况的末尾拿掉,然后再放进去三种情况中可以选择的两个最大的进去就好了?
那么方法就很明显了:
我这里使用的是双端队列,因为一旦一开始排序之后,每本书的相对位置就不会改变。
我用s表示当前在答案里的书,rt表示当前可以选择的书。
那么首先考虑的是是否能在m本书之内让每个人都得到k本喜欢的书。
然后的话
while(s[3].size()+min(mi,(m-(int)s[3].size())/2)<k||s[3].size()+rt[1].size()+rt[2].size()+rt[0].size()<m) 这个表示最少需要放的(1,1)的个数
再然后,我们就像刚才所说的,新增(1,1)的时候把下面三种的末尾抛掉,再塞两个进来。注意一些细节,我这里就不赘述了
#include<bits/stdc++.h> using namespace std; const int N=2e5+5; struct node{ int tim,a,b,id; bool operator< (const node& aa)const { return tim<aa.tim; } }a[N]; deque<node>s[5],rt[5]; int vis[N]; vector<int>ad,de; int main() { int n,m,k; scanf("
文章目录 前言示例代码路径重要概念 简单应用Demo简单分析总结 进阶使用注解@EventListener异步监听@Async spring监听器RequestHandleEvent 观察者模式概念角色示例代码 源码解析事件广播器Spring事件机制流程流程解释 附录加载监听器的几个细节addApplicationListenerBeanaddApplicationListener 如何读的源码把示例项目跑起来在合适的位置打断点 总结参考链接 前言 事件机制(Event)是spring的重要功能之一。本文将从该功能的用法/和监听器的关系/应用的设计模式/源码讲解等几个方面,由浅入深做全方位讲解。
虽然是Spring的重要功能之一,但在大部分人的日常开发中,却很少直接应用该功能。
一句话概括用法场景:一个地方发出个通知,很多其他地方能收到通知并作出相应的动作。
示例代码路径 后面的Demo以一个简单的Springboot项目为基础(文中也会贴出重要代码)。项目路径
重要概念 在事件机制中有以下几个重要概念:
事件事件发布者(一个)事件监听者(多个) 简单应用 Demo 事件
package com.yc.blog.springboot.event.demo1; import org.springframework.context.ApplicationEvent; /** * 事件 */ public class MyEvent1 extends ApplicationEvent { private static final long serialVersionUID = 1L; /** * 自定义事件消息内容 */ private String message; /** * 为什么要这么写构造方法? * 因为父类没有默认构造器,子类必须手动调用父类的那个构造器ApplicationEvent(Object source) * @param source * @param message */ public MyEvent1(Object source, String message) { super(source); this.
PS域和CS域 参考链接:https://zhidao.baidu.com/question/1691360411931618948.html PS域,分组交换(Packet Switch),有时又称分组业务(Packet Service),这是移动通信网络zhi发展的早期,针对不同的业务需求及实现方式不同,而提供的分类概念。早期的移动通信网络,主要提供语音业务,也就是我们常说的打电话。
语音业务在通信网络上通常需要独占式的电路通路资源,不同用户之间要能通话就需要通信网络提供电路交换功能,将彼此独占式的电路通路资源互相接通,所以称语音业务为电路交换(Circuit Switch)。
CS(Circuit SwitchedDomain)域:指核心网中为用户业务提供电路交换类型连接的所有网元实体,以及所有支持相关信令的网元实体。电路交换型连接在连接建立时分配专用网络资源,在连接释放时释放专用资源。
扩展资料PS概念源于通用无线分组业务(GPRS,General Packet Radio Service)。GPRS一般被认为是移动通信的2.5代技术(2.5G),而PS是第三代移动通信技术提出的概念,它在2.5G的基础上实现了功能扩展和增强,其最终目的是提供高速的分组数据业务。第三代移动通信技术,国际上主要有三大标准:WCDMA、TD-SCDMA、CDMA2000。其实不管是在WCDMA、TD-SCDMA还是在CDMA2000中,或是在传统的GSM网络中,都是存在PS和CS这两个概念的,这是移动通信技术发展到一定阶段的必然产物。
网络制式核心网CS域ps域2G语音业务 3G语音业务数据业务4G(LTE)语音业务VOLTE(语音业务)数据业务5G语音业务VOLTE(语音业务)数据业务 CS:Circuit Switch表面意思就是电路交换;
PS:Packet Switch表面意思就是分组交换。
PS域为用户提供分组型数据业务”。PS域源于通用无线分组业务(GPRS,General Packet RadioService),在GPRS(2.5G技术)的基础上实现了功能扩展和增强,其最终目的是提供高速的分组数据业务。
PS域和CS域的区别:
不管是在W、TD还是CDMA中,还是在传统的GSM中,都是存在这两个概念的。CS业务主要是包括一些语音业务,如64K语音等等。但是也包括一些电路型数据业务,最为常见和经典的就是传真;PS业务就是常见的数据业务,也包括流媒体业务、VOIP等等。一些网络,如WLAN、LTE等都是没有CS业务的,他们的语音业务都只能通过VOIP来实现。
CS域是电路承载域,提供语音业务和传真服务,PS域是数据域,走得是IP,用于手机上网,但也包括流媒体业务、VOIP等等。
在3G下,接入网同时连接CS和PS,即核心网分割为CS,PS,打电话信号走CS,数据业务信号走PS。
运营商功能普通终端XX模组IMS/VOLTE打开IMS/VOLTE关闭IMS/VOLTE打开IMS/VOLTE关闭发短信打电话发短信打电话发短信打电话发短信打电话移动(LTE)走VOLTE,
不回落走VOLTE,
不回落回落2g/3g回落2g/3g走VOLTE,不回落走VOLTE,不回落回落2g/3g回落2g/3g联通(LTE)电信(LTE)需打开IMS/VOLTE功能:
1、SIM卡开通IMS功能
2、模组侧打开IMS功能
3、网络侧配置IMS功能需打开IMS/VOLTE功能:
1、SIM卡开通IMS功能
2、模组侧打开IMS功能
3、网络侧配置IMS功能模组不支持电信2g/3g:
IMS关闭后就不能发短信模组不支持电信2g/3g:
IMS关闭后就不能打电话移动(SA) 回落到VOLTE:
1、SIM卡开通IMS功能
2、模组侧打开IMS功能
3、网络侧配置IMS功能回落到VOLTE:
1、SIM卡开通IMS功能
2、模组侧打开IMS功能
3、网络侧配置IMS功能回落2g/3g,
但回落时间较长,需5s以上回落2g/3g,
但回落时间较长,需5s以上联通(SA)电信(SA)模组不支持电信2g/3g:
IMS关闭后就不能发短信模组不支持电信2g/3g:
IMS关闭后就不能发短信