点分治适合处理大规模的树上路径信息问题。
给定一棵 \(n\) 个点树和一个整数 \(k\),求树上两点间的距离小于等于 \(k\) 的点对有多少。
对于这个题,如果我们进行 \(O_{n^3}\) 搜索,那只要 \(n\) 一大,铁定超时。
所以,我们要用一个更优秀的解法,这就是我们的点分治。
淀粉质可好吃了
typedef pair<int, int> pii;
const int N = 4e4 + 10;
int n, k, rt, ans, sum;
int siz[N], maxp[N], dis[N], ok[N];
bool vis[N];
vector<pii> son[N];
n
: 点数;
k
: 限定距离;
rt
: 根节点;
sum
: 总结点数(找重心要用到);
siz
: 子树大小;
maxp
: 最大的子树的大小;
dis
: 每个节点到根节点的距离;
ok
: 栈;
vis
: 标记;
son
: 存图。
为什么是找重心?
其所有的子树中最大的子树节点数最少,在所有点中,重心是最优的选择。
找到重心后,以重心为根开始操作。
void get_root(int u, int fat) {
siz[u] = 1;
maxp[u] = 0;
for (pii it : son[u]) {
int v = it.first;
if (v == fat || vis[v]) continue;
get_root(v, u);
siz[u] += siz[v];
maxp[u] = max(maxp[u], siz[v]);
}
maxp[u] = max(maxp[u], sum - siz[u]);
if (maxp[u] < maxp[rt]) rt = u;
}
这里并不是很难。
对于每个根节点,我们进行搜索,会得到每个节点到根节点的距离。
我们现在要求出经过根节点的距离小于等于 \(k\) 的点对个数。
我们将所有点的距离从小到大排一个序,设置左右两个指针,如果左指针和右指针所指向的节点到根节点的距离小于等于 \(k\),则两个指针之间所有的节点到左指针所指向的节点的距离都小于等于 \(k\),与此同时 l ++
,如果左右指针所指向的节点的距离之和大于 \(k\),那么右指针就要左移,即 -- r
。
然后我们对每个节点都这样搜一遍,将答案加出来,就可以轻松加愉快的切掉这个问题了
吗?
考虑一下,如果是下面这种情况
假设 \(k = 5\),那么以 \(1\) 为根节点时,\(4\) 与 \(5\) 很显然是符合的,我们将它加入答案。
然后,当我们又以 \(3\) 为根节点时,\(4\) 和 \(5\) 这个点对我们就又统计了一次。
有什么问题?重复啦!
原因也很简单,因为 \(4\) 和 \(5\) 在同一个子树内,因此只要它们在这个大的树内符合要求,那么它们在它们的小子树内也一定符合要求,那么就一定会有重复,因此,利用容斥的原理,我们先求出总的答案,然后再减去重复的部分。
如何检验重复的部分呢?
我们发现它们共同经过了一条边 \(1 - 3\),所以我们再次搜索,这次直接初始化 dis[3] = 1
,然后其他的依旧按照操作,最后如果他们的距离小于等于 \(k\),则这就是重复的部分,统计一下,最后减去即可。
减去之后,就在子树里找重心,设置新的根节点,开始新的答案统计,与此同时,我们要将原来的根节点打上标记,防止搜索范围离开了这个子树。
(或许这就是点“分治”的所在,搜完一个重心后,相当于把这个重心删除,然后就将一颗树分成多个互相之间没有联系的小子树,各自进行搜索)
int calc(int u, int val) {
ok[0] = 0;
dis[u] = val;
dfs(u, 0);
sort(ok + 1, ok + ok[0] + 1);
int cnt = 0, l = 1, r = ok[0];
while (l < r) {
if (ok[l] + ok[r] <= k) {
cnt += (r - l ++);
}
else {
r --;
}
}
return cnt;
}
void work(int u) {
ans += calc(u, 0);
vis[u] = 1;
for (pii it : son[u]) {
int v = it.first, w = it.second;
if (vis[v]) continue;
ans -= calc(v, w);
maxp[rt = 0] = sum = siz[v];
get_root(v, 0);
work(rt);
}
}
关于 sum = siz[v];
,当我们再次找重心时,是要在这个子树中找重心,不能超出这个子树,因此要将总个数也设为 siz[v]
。
这个,应该就没什么好说的了。
void dfs(int u, int fat) {
ok[++ ok[0]] = dis[u];
siz[u] = 1;
for (pii it : son[u]) {
int v = it.first, w = it.second;
if (v == fat || vis[v]) continue;
dis[v] = dis[u] + w;
dfs(v, u);
siz[u] += siz[v];
}
}
看到这,你已经看完了点分治的核心步骤,让我们把代码整合一下,去切掉这道模板题 Tree。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 4e4 + 10;
int n, k, rt, ans, sum;
int siz[N], maxp[N], dis[N], ok[N];
bool vis[N];
vector<pii> son[N];
inline ll read() {
ll x = 0;
int fg = 0;
char ch = getchar();
while (ch < '0' || ch > '9') {
fg |= (ch == '-');
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + (ch ^ 48);
ch = getchar();
}
return fg ? ~x + 1 : x;
}
void get_root(int u, int fat) {
siz[u] = 1;
maxp[u] = 0;
for (pii it : son[u]) {
int v = it.first;
if (v == fat || vis[v]) continue;
get_root(v, u);
siz[u] += siz[v];
maxp[u] = max(maxp[u], siz[v]);
}
maxp[u] = max(maxp[u], sum - siz[u]);
if (maxp[u] < maxp[rt]) rt = u;
}
void dfs(int u, int fat) {
ok[++ ok[0]] = dis[u];
siz[u] = 1;
for (pii it : son[u]) {
int v = it.first, w = it.second;
if (v == fat || vis[v]) continue;
dis[v] = dis[u] + w;
dfs(v, u);
siz[u] += siz[v];
}
}
int calc(int u, int val) {
ok[0] = 0;
dis[u] = val;
dfs(u, 0);
sort(ok + 1, ok + ok[0] + 1);
int cnt = 0, l = 1, r = ok[0];
while (l < r) {
if (ok[l] + ok[r] <= k) {
cnt += (r - l ++);
}
else {
r --;
}
}
return cnt;
}
void work(int u) {
ans += calc(u, 0);
vis[u] = 1;
for (pii it : son[u]) {
int v = it.first, w = it.second;
if (vis[v]) continue;
ans -= calc(v, w);
maxp[rt = 0] = sum = siz[v];
get_root(v, 0);
work(rt);
}
}
int main() {
n = read();
for (int i = 1, u, v, w; i < n; ++ i) {
u = read(), v = read(), w = read();
son[u].push_back({v, w});
son[v].push_back({u, w});
}
k = read();
maxp[rt = 0] = sum = n;
get_root(1, 0);
work(rt);
printf("%d\n", ans);
return 0;
}
模板题(大雾)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, ll> pil;
const int N = 1e4 + 5;
int n, m, sum, rt;
int q[N], siz[N], maxs[N], can[N], dis[N];
int tp[N];
bool ok[N], vis[N];
vector<pil> son[N];
bool cmp(int x, int y) {
return dis[x] < dis[y];
}
void get_root(int u, int fat, int tot) {
siz[u] = 1;
maxs[u] = 0;
for (auto [v, w] : son[u]) {
if (v == fat || vis[v]) continue;
get_root(v, u, tot);
siz[u] += siz[v];
maxs[u] = max(siz[v], maxs[u]);
}
maxs[u] = max(maxs[u], tot - siz[u]);
if (!rt || maxs[u] < maxs[rt]) {
rt = u;
}
}
void dfs(int u, int fat, int d, int from) {
can[++ can[0]] = u;
dis[u] = d;
tp[u] = from;
for (auto [v, w] : son[u]) {
if (v == fat || vis[v]) continue;
dfs(v, u, d + w, from);
}
}
void calc(int u) {
can[0] = 0;
can[++ can[0]] = u;
dis[u] = 0;
tp[u] = u;
for (auto [v, w] : son[u]) {
if (vis[v]) continue;
dfs(v, u, w, v);
}
sort(can + 1, can + can[0] + 1, cmp);
for (int i = 1; i <= m; ++ i) {
int l = 1, r = can[0];
if (ok[i]) continue;
while (l < r) {
if (dis[can[l]] + dis[can[r]] > q[i]) {
r --;
}
else if (dis[can[l]] + dis[can[r]] < q[i]) {
++ l;
}
else if (tp[can[l]] == tp[can[r]]) {
if (dis[can[r]] == dis[can[r - 1]]) {
-- r;
}
else ++ l;
}
else {
ok[i] = true;
break;
}
}
}
}
void work(int u) {
vis[u] = true;
calc(u);
for (auto [v, w] : son[u]) {
if (vis[v]) continue;
rt = 0;
get_root(v, 0, siz[v]);
work(rt);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for (int i = 1, x, y, z; i < n; ++ i) {
cin >> x >> y >> z;
son[x].push_back({y, z});
son[y].push_back({x, z});
}
for (int i = 1; i <= m; ++ i) {
cin >> q[i];
if (!q[i]) ok[i] = 1;
}
maxs[0] = n;
get_root(1, 0, n);
work(rt);
for (int i = 1; i <= m; ++ i) {
if (ok[i]) {
cout << "AYE" << '\n';
}
else {
cout << "NAY" << '\n';
}
}
return 0;
}
大家好,又见面了,我是你们的朋友全栈君。openssl安装教程1.安装包安装1.1所需资源链接1.2安装流程1.3测试是否安装成功1.4安装过程中的问题2.自己编译源码再安装1.安装包安装1.1所需资源链接openssl安装包下载地址:http://slproweb.com/products/Win32OpenSSL.html 如果用谷歌浏览器打开的话,可以翻译成中文: 对应英文如下: 根据自己电脑的配置选择需要的版本,我这里选择的第1个Win64OpenSSLv1.1.1iLight。1.2安装流程下载好之后,直接双击即可安装。 安装过程没什么可说的,一般直接点下一步即可。如果想更换安装路径,记得更换安装路径,我习惯安装在D盘的ProgramFiles路径下。安装完之后,需要配置一下环境变量。右击“我的电脑”->属性->高级系统设置,在系统属性界面选择“高级”->环境变量,如下图。 在系统变量中选中“Path”,点击“编辑”,如下图。 将你的安装路径复制到最后面,注意跟前面的用分号“;”隔开。我安装在了D盘下的ProgramFiles路径下。OpenSSL
示例:在Windows上新建一个文本文件,输入以下脚本内容,修改文本文件后缀txt为bat后即可运行!(默认情况下无法直接修改文本后缀,需要修改文件编码。)@echo该喝水了,快起来喝水! @choice/t180/dy/n>nul复制设置显示文本后缀Windows桌面上双击“我的电脑”,点击“查看”,勾选上“文件扩展名”,即可显示文件后缀名并且后缀可直接修改!运行bat脚本:默认情况下,若在bat脚本文件中出现中文字符,运行时则会出现展示乱码问题,若要避免运行时乱码问题,需要修改文本文件编码!解决方法:选中需要修改的文件,点击鼠标右键,选择“编辑”,进入文件编辑页面后,点击“文件”,选择“另存为”,在另存为时选择“ANSI”编码,点击保存即可!再次运行bat脚本:可以看到在修改完bat脚本文件的编码之后,再运行bat脚本就已经不会出现乱码的问题了!
前言门面模式也叫外观模式,是一种结构型设计模式,能为程序库、框架或其他复杂类提供一个简单的接口。1使用场景门面模式可以说是在工作中使用非常多的一种设计模式了,比如常用的slf4j。下面简单介绍常用的使用场景:为远程接口设计统一入口比如需要调用微信支付宝支付,里面一大堆参数,参数什么也不一样,这时候就可以统一封装一个接口,然后小伙伴们使用的时候,只需要调用封装的接口就可以了。也不用担心同样是状态,这里叫status,那里叫orderStatus了。反正对外都是一个统一的门面,你自己定义即可。好处统一封装门面的好处,就是可以Mock。这也是我最近了解到的,之前都是一把嗦,谁管junit。Mock就是说在junit测试中,使用@MockBean注入一个mock对象,然后自己定义返回。Mockito.when(xxxFacadeService.methodX()).thenReturn(mockBean); 复制就是调用某个接口的时候,返回自己mock的对象。这个我也是才发现的,因为我试着使用@MockBean注解Dubbo接口的对象,但是并不行。不过还是可以变通的,所有的调用外部接口的地方,
所谓发布指的是,如何让集群之外的主机能访问服务创建一个svcCluster-IP只有集群内部可访问(图中命令显示只能通过80端口访问)SVC并不是所有协议都能访问NodePort为某个服务配置了NodePort,此NodePort会在所有节点上映射加上--tpye=NodePort会随机映射到物理机的一个30000以上的端口[root@vms61chap9-svc]#kubectlexpose--name=svc1deploymentweb1--port=80--target-port=80--type=NodePort service/svc1exposed [root@vms61chap9-svc]#kubectlgetsvc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc1 NodePort 10.100.69.97 <none> 80:32217/TCP 3s 复制所有节点均可访问所有节点均可访问所有节点均可访问如果忘了指定type,也可在创建好svc后通过edit
前端的发展历程什么是前端前端:针对浏览器的开发,代码在浏览器运行后端:针对服务器的开发,代码在服务器运行前端三剑客HTMLCSSJavaScriptHTMLHTML(超文本标记语言——HyperTextMarkupLanguage)是构成Web世界的基石。HTML是一种基础技术,常与CSS、JavaScript一起被众多网站用于设计令人赏心悦目的网页、网页应用程序以及移动应用程序的用户界面。 超文本标记语言(第一版)——在1993年6月作为互联网工程工作小组(IETF)工作草案发布(并非标准): HTML2.0——1995年11月作为RFC1866发布,在RFC2854于2000年6月发布之后被宣布已经过时 HTML3.2——1997年1月14日,W3C推荐标准 HTML4.0——1997年12月18日,W3C推荐标准 HTML4.01(微小改进)——1999年12月24日,W3C推荐标准 HTML5——2014年10月28日,W3C推荐标准 CSS层叠样式表(英文全称:CascadingStyleSheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(
镁客网特别对吴恩达先生进行了专访,邀请他谈谈另一面的人工智能,谈谈科学里的人文情怀。 策划&撰文:申小姐、巫盼 昨天,在2018中国人工智能峰会上,吴恩达先生受邀出席,并发表了《如何用人工智能为商业赋能》的主题演讲。深度参与过百度和谷歌的人工智能转型,对于AI如何切实得帮助传统企业转型,从而带来真真实实的赋能效应,吴恩达在现场表达了很多自己的观点。 他谈了AI如何渗透进传统企业管理体系,探讨了AI技术与场景融合的逻辑,通过企业案例来分析了如何运用AI更好地进行商业策略规划,给了CEO们三个建议,最后他说,AI的产业未来,一定需要政府、企业与学校的共同协作。 这是演讲中的吴恩达,而在演讲之外,镁客网特别对吴恩达先生进行了专访,邀请他谈谈另一面的人工智能,谈谈科学里的人文情怀。 8岁离开中国香港的吴恩达广东话说的并不算好,倒是他的中文比想象中要流利很多。2017年创立了在线教育平台Deeplearning.ai、赋能传统企业的Landing.ai以及AIFund创投三家公司的他,也完全没有商人的模样,还是那个非常有亲和力的科学家。在中文词汇过于复杂的时候,他也会用眼神表示歉意,转而
1.接口描述接口请求域名:cfw.tencentcloudapi.com。 获取当前用户接入nat防火墙的所有子网数及natfw实例个数 默认接口请求频率限制:20次/秒。 APIExplorer提供了在线调用、签名验证、SDK代码生成和快速检索接口等能力。您可查看每次调用的请求内容和返回结果以及自动生成SDK调用示例。 2.输入参数以下请求参数列表仅列出了接口请求参数和部分公共参数,完整公共参数列表见公共请求参数。 参数名称 必选 类型 描述 Action 是 String 公共参数,本接口取值:DescribeNatFwInfoCount。 Version 是 String 公共参数,本接口取值:2019-09-04。 Region 否 String 公共参数,本接口不需要传递此参数。 3.输出参数 参数名称 类型 描述 ReturnMsg String 返回参数注意:此字段可能返回null,表示取不到有效值。 NatFwInsCount Integer 当前租户的nat实例个数注意:此字段可能返回null,表示取不到有效值
前端面试一般喜欢问: 请手写一个带取消功能的延迟函数,axios取消功能的原理是什么? 如何中断请求fetch的原理分析和应用? 在看来《使用AbortController终止fetch请求》,觉得写的非常详细,于是提炼下笔记: AbortController背景介绍 在现在的浏览器中,有两种主要的方法发送请求:XMLHttpRequest和fetch。XMLHttpRequest这个接口在浏览器中存在很长一段时间了,fetch则是ES2015引入的特性。 XMLHttpRequest可以在请求中途终止(abortable)。举个例子 let xhr = new XMLHttpRequest(); xhr.method = 'GET'; xhr.url = 'https://slowmo.glitch.me/5000'; xhr.open(method, url, true); xhr.send(); // Abort the r
Question1、HTTPStatus500-UnabletocompileclassforJSP:'***'cannotberesolvedtoatype 原因分析:cannotberesolvedtoatype基本上是该类没有被识别出来,编译的时候,编译路径下没有该类对应的库文件, 解决方法: 1、拷贝类对应的jar到tomcatlib目录下:C:\ProgramFiles\Java\apache-tomcat-8.0.9\lib 2、关闭tomcat服务器:执行bat文件C:\ProgramFiles\Java\apache-tomcat-8.0.9\bin\shutdown.bat 3、重新启动tomcat服务器,重新访问页面,该问题现象消失 Question2、HTTPStatus500-invaliddriverclassname:"java.lang.ClassNotFoundException:com.mysql.jdbc.Driver" 原因分析:JSP程序访问mysql数据库,没有正确识别mysql的jdbc驱动,通过检查发现,当前windows系统并未安装mys
Can referencehttps://help.sap.com/saphelp_46c/helpdata/en/fd/45bc639d6411d189b60000e829fbbd/frameset.htm 1.物料主数据设置 T-code:MM03 关注MRP1,MRP2,Forecast视图 MRP1视图: MRP2视图: Forecast视图: 2.执行forecast T-code:MP30 点击HistoricalValues(因为物料主数据中填的参数Historicalperiods是12,所以会显示过去12个月的数据): 点击ForecastValues:出现报错: 返回点击Execute: 选择一个Date:系统会计算出预测值。 这里的红色数据是可以更改的。点击保存,到MD04看看。
海明码学习前提 记住几个要点: 不要用异或套用公式!!!!题目随便变几个变死你! 看完这篇博客不要看别的博客!!!!别的人瞎写的坑死你 学习海明码之前,我们要约定3个原则: 海明码只能检测出2位错,纠1位错(因此不要问如果3位错怎么办等幼稚问题)。 海明码默认进行偶校验(除非特殊说明使用奇校验)。 海明码是一串由0和1组成的序列(除01外没有其他的值,记住了!这是重点) 如果下面有任何无法理解的问题,反复看上面三个原则,下面再也不赘述。 前提:奇偶校验 奇校验:这串序列1的个数如果为偶数则在前面加个1,使1的个数变成奇数,否则加0。 偶校验:这串序列1的个数如果为奇数则在前面加个1,使1的个数变成偶数,否则加0。 例子:1111奇校验就是11111偶校验就是01111 1110奇校验就是01110偶校验就是11110 特性是检测一位错,无法纠错。 概述:海明码的构成 例如如下序列: 1100 我们想要让其变成海明码只需如下操作 1.算出校验位数k 正常情况下我们需要如下此操作: 2^k>=k+数据位数+1 这里等于3 2.确定校验位在海明码中的位置 这里按2^k次幂留出来
form1: usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.IO; usingSystem.Linq; usingSystem.Text; usingSystem.Threading.Tasks; usingSystem.Windows.Forms; namespace简易记事本 { publicpartialclassForm1:Form { publicForm1() { InitializeComponent(); } ///<summary> ///全局变量,当前打开的文件路径储存在隐藏的marklocationlabel1.text中 ///</summary> filesoperatorfop=newfilesoperator();//文件操作类 Dictionary<string,string>Dc=newDic
/** *@description超出字符截取 *@param{*}clsclass名称 */ functionfixLine(cls){ console.time(); $("."+cls).each(function(){ var_this=$(this); varcontent=_this.attr('data-content') _this.text(content); varoutHeight=_this.parent().height(); for(vari=0;i<content.length+1;i+=2){ _this.text(content.substr(0,i)) if(outHeight<_this[0].scrollHeight-5){ _this.css('overflow','hidden').text(content.substr(0,i-6)+'...') break; } } }); css设置高度父级 复制
mysql在存在主键冲突或者唯一键冲突的情况下,根据插入策略不同,一般有以下三种避免方法。1、insertignore2、replaceinto3、insertonduplicatekeyupdate 注意,除非表有一个PRIMARYKEY或UNIQUE索引,否则,使用以上三个语句没有意义,与使用单纯的INSERTINTO相同。 一、insertignore insertignore会忽略数据库中已经存在的数据(根据主键或者唯一索引判断),如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据. Case: 表结构如下: root:test>showcreatetablet3\G ***************************1.row*************************** Table:t3 CreateTable:CREATETABLE`t3`( `id`int(11)NOTNULLAUTO_INCREMENT, `c1`int(11)DEFAULTNULL, `c2`varchar(20)DEFAULTNULL, `c3`int(11)DE
[array]$servers=Get-SPServer|?{$_.Role-eq"Application"} $farm=Get-SPFarm foreach($serverin$servers) { Write-Host"RestartingTimerJobon$server" $Service=Get-WmiObject-Computer$server.nameWin32_Service-Filter"Name='SPTimerV4'" if($Service-ne$null) { $Service.InvokeMethod('StopService',$null) Start-Sleep-s7 $service.InvokeMethod('StartService',$null) Start-Sleep-s7 Write-Host"TimerJobsuccessfullyrestartedon$server" } else { write-host-ForegroundColorYellow"CouldnotfindSharePoint2010TimerServiceon$se
数据治理是在数据生命周期(从获取、使用到处置)内对其进行管理的原则性方法。 每个组织都需要数据治理。随着各行各业中的企业进行数字化转型,数据已迅速成为他们拥有的最有价值的资源。 高级管理人员需要使用准确、及时的数据来做出战略性业务决策。营销和销售专业人员需要使用可靠的数据来了解客户的需求。采购和供应链管理人员需要使用准确的数据来管理库存以及最大程度地降低制造费用。合规人员需要证明数据是按照内部和外部授权书进行处理的。 数据治理的定义 数据治理是指为确保数据安全、私有、准确、可用和易用所执行的所有操作。它包括人们必须采取的行动、必须遵循的流程以及在整个数据生命周期中为其提供支持的技术。 数据治理意味着设置适用于收集、存储、处理和处置数据的内部标准,即数据策略。它规定了谁可以访问哪些数据以及哪些数据应受治理。数据治理还涉及遵循行业协会、政府机构和其他利益相关者设定的外部标准。 数据治理有哪些益处? 做出更明智、更及时的决策 整个组织中的用户都可以获得数据以联系和服务客户、设计
1.环境检测: 检测是否已安装mysql: 1 rpm–qa|grep mysql 若有检测出与mysql相关的文件,如下, 则,执行 1 rpm-e--nodepsmysql-libs-5.1.66-2.el6_3.x86_64 进行强制卸载。 2.安装cmake: MySQL5.5的编译工具由Autotool转变为了cmake,因此,需要安装cmake,安装cmake需要依赖gcc和gc++,就得先安装gcc和gcc-c++,依次安装以下软件包: 1 rpm-ivhppl-0.10.2-11.el6.x86_64.rpm 1 rpm-ivhcloog-ppl-0.15.7-1.2.el6.x86_64.rpm
前言: 这是项目实践系列,算是中高级系列博文,用于为项目开发过程中不好解决的问题提出解决方案的.不属于入门级系列.解释起来也比较跳跃,只讲重点. 因为有网友的项目需求,所以提前把这些解决方案做出来并分享. 问题: Blazor自己是携带一个简单的路由功能的,当切换Url的时候,整个通过把RouteData传递给App.razor加载MainLayout,实现页面刷新的目的. 如果跳转到另外一个页面,然后再跳回来的时候,希望原来页面不刷新,保留之前的状态,例如搜索条件,那么怎么办? 解决过程: 结合视频,图文观看效果最好: https://www.bilibili.com/video/BV1g54y1R7uX/ 1.现在简单说说,这种情况的源头在哪里.2. App.razor文件使用了RouteView来实现路由3. routeData是包含页面类型,以及页面参数的.4. 然而默认的实现里,RouteView是不带状态的5. MainLayout虽然得到了内容的RenderFragment,6. 然而这个RenderFragment是由R
关于<video>标签所⽀持的视频格式和编码:MP4=MPEG4⽂件使⽤H264视频编解码器和AAC⾳频编解码器WebM=WebM⽂件使⽤VP8视频编解码器和Vorbis⾳频编解码器Ogg=Ogg⽂件使⽤Theora视频编解码器和Vorbis⾳频编解码器 所以在使用<video>前请确保文件格式和编码。 一:现象 在使用<video>播放视频时发现在iOS中无法播放,后台输出二进制流,ContentType="video/mp4"。 但是直接返回一个.mp4的视频是可以播放的。说明视频格式没问题。 二:查找问题 查看客户端请求发现请求头中: 第一次请求时:Range:bytes=0-1。这是范围请求,相当于一个嗅探。要求后台必须有相应格式的返回信息。 Range:分段请求头,bytes=0-1表示获取0-1的位置的2个字节。 这就要求服务器返回: Accept-Ranges:bytes 接收字节请求Content-Length:2