梦总是有会醒来的时候,不会醒的梦总有一天会变成悲伤。

前言

这次考试的思维含量有一点大(此时距离考试还有 7min 而我的总结还没写完。。)

但是对于以前的考试来讲还是有所进步的,毕竟在考试的时候还是第一次尝试着自己推柿子,最后也是成功的推出部分分的柿子。。

唯一遗憾的一点就是在 wzr 的领导下,我在 256MB 的内存下开了 \(10^4\times 10^4\) 的 long long 数组。

然后,就 MLE 0pts 了,我的 35 分就。。。(现在距离所谓的考试还有 2min ,但是考试突然没了)

再然后又说 14:40 开始考。。。起起伏伏。。。

对于第三题的话,裸的暴力,处理之后直接 sort 就可以搞到 60pts ,但是我一想到 sort 的复杂度就直接开了一个数组,手动一个一个按顺序插入,最后弄巧成拙,喜提 0pts。

虽然现在正在考试中,但这并不影响我写之前的考试总结,毕竟仅剩下 7min 了,我对于别的题也没有什么好的想法。

T1 夜莺与玫瑰

解题思路

对于 60pts 来说,显然的是要一个对于每一次询问 \(\mathcal{{O}}(n^2)\) 查询的办法。

于是我苦死冥想了整整 100min 想到了这个部分分。

(第一次隔天写文章。。),对于每一种线的最短线段一定会满足 \(\gcd(i-1,j-1)=1\) 。

在下面计算以及说明的时候为了方便,我们把所有的初始变量都减去一个 1 ,所以关于下面的说明可能会口胡多或者少一个 1 读者请意会一下(逃。

然后在 \((n,m)\) 的区间内,对于最短的线段(算上重复的)一共会有 \((n-i)\times (m-j)\) 条。

但是通过画图就可以发现 重复的就会有 \((n-2\times i)\times (m-2\times j)\) 条。

也就是下面的柿子:

\[\sum\limits_{i=1}^{n-1}\sum\limits_{j=1}^{m-1}[\gcd(i,j)=1]((n-i)\times(m-j)-\max(n-2\times i,0)\times \max(m-2\times j,0))
\]

对于这个柿子维护二维前缀和。

第一个前缀和计算范围内的 \(\gcd\) 的数量,可以理解为从某一点出发的最短线段的个数。

然后在此基础上维护一个二维前缀和 \(pre_{n,m}=[\gcd(i,j)=1]((n-i)\times(m-j)\)。

然后我们尝试把这个柿子运用到之前的柿子上发现, 其实:

\[(n-2\times i)\times (m-2\times j)=4\times(\dfrac{n}{2}-i)\times(\dfrac{m}{2}-j)=4\times pre_{\frac{n}{2},\frac{m}{2}}
\]

接下来就可以直接套用公式并且对于奇数的情况进行处理就好了。

code

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e4+10,M=4e3+10,mod=1073741824;
int T,n,m,f[M][M],vis[M][M],pre[M][M];
struct Node
{
int x,y;
}q[N];
int Gcd(int x,int y)
{
if(!y) return x;
return Gcd(y,x%y);
}
void Init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
vis[i][j]=(Gcd(i,j)==1);
vis[i][j]+=vis[i][j-1]+vis[i-1][j]-vis[i-1][j-1];
pre[i][j]=vis[i][j]+pre[i][j-1]+pre[i-1][j]-pre[i-1][j-1];
}
}
int solve(int x,int y)
{
int ans=0,mix=x/2,miy=y/2;
ans=pre[x-1][y-1];
ans=(ans+(4ll*mod-4*pre[mix-1][miy-1]))%mod;
if(x&1) for(int i=1;i<=miy;i++) ans=(ans+1ll*(2ll*mod-2ll*vis[mix][i-1]))%mod;
if(y&1) for(int i=1;i<=mix;i++) ans=(ans+1ll*(2ll*mod-2ll*vis[i-1][miy]))%mod;
if(x&1 && y&1) ans=(ans+1ll*(mod-vis[mix][miy]))%mod;
return (ans*2+x+y)%mod;
}
signed main()
{
T=read();
for(int i=1;i<=T;i++)
{
q[i].x=read();
q[i].y=read();
n=max(n,q[i].x);
m=max(m,q[i].y);
}
Init();
for(int i=1;i<=T;i++)
printf("%d\n",solve(q[i].x,q[i].y));
return 0;
}

T2 影子

解题思路

对于暴力算法可以分别以每个节点为根,分别查询这个节点到其他节点的距离以及最小值。

时间复杂度 \(\mathcal{O}(n^2)\) 空间复杂度 \(\mathcal{O}(n)\)

然后在考场上我搞了一个 \(n^2\) 的复杂度,再然后就 MLE 0pts,痛失 35pts(\(code\)) 。

正解是首先对于所有的节点按节点值从大到小进行排序(这样在搞的时候就不用考虑节点权值的关系了),然后把当前集合中的最长路的长度和两个端点用冰茶几维护。

用冰茶几合并这个节点以及与他有连边的节点所在的联通块。

维护的时候主要分为两大种情况:

  1. 原来的两个联通块分别的长度

  2. 由两个最长路的两个端点分别连接而成,共有 4 种。

每次冰茶几维护直接用两种值的乘积,更新既可,代码实现不算太难。。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=1e5+10,M=2e4,INF=1e9;
int n,m,T,ans,tim,fat[N],dep[N],son[N],siz[N],dfn[N],fa[N],topp[N],dis[N],clo[N];
int tot,head[N<<1],nxt[N<<1],ver[N<<1],edge[N<<1];
struct Node
{
int id,val;
}s[N];
struct Road
{
int l,r,len;
void clear()
{
l=r=len=0;
}
}pat[N],dist[10];
void add_edge(int x,int y,int val)
{
ver[++tot]=y;
edge[tot]=val;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs1(int x)
{
pat[x].l=pat[x].r=x;
siz[x]=1;
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(siz[to]) continue ;
dis[to]=dis[x]+edge[i];
dep[to]=dep[x]+1;
fat[to]=x;
dfs1(to);
siz[x]+=siz[to];
if(siz[to]>siz[son[x]])
son[x]=to;
}
}
void dfs2(int x,int tp)
{
topp[x]=tp;
dfn[x]=++tim;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=nxt[i])
if(!dfn[ver[i]])
dfs2(ver[i],ver[i]);
}
int LCA(int x,int y)
{
if(!x||!y) return 0;
if(x==y) return x;
while(topp[x]^topp[y])
{
if(dep[topp[x]]<dep[topp[y]])
swap(x,y);
x=fat[topp[x]];
}
if(dep[x]>dep[y])
swap(x,y);
return x;
}
bool comp(Node x,Node y)
{
return x.val>y.val;
}
int find(int x)
{
if(fa[x]==x) return fa[x];
return fa[x]=find(fa[x]);
}
int Dist(int x,int y)
{
return dis[x]+dis[y]-2*dis[LCA(x,y)];
}
bool cmp(Road x,Road y)
{
return x.len>y.len;
}
void merge(int x,int y)
{
int minn=clo[x];
x=fa[find(x)];
y=fa[find(y)];
dist[1]=pat[x];
dist[2]=pat[y];
dist[3]=(Road){pat[x].l,pat[y].l,Dist(pat[x].l,pat[y].l)};
dist[4]=(Road){pat[x].l,pat[y].r,Dist(pat[x].l,pat[y].r)};
dist[5]=(Road){pat[x].r,pat[y].l,Dist(pat[x].r,pat[y].l)};
dist[6]=(Road){pat[x].r,pat[y].r,Dist(pat[x].r,pat[y].r)};
sort(dist+1,dist+7,cmp);
pat[x]=dist[1];
fa[y]=x;
ans=max(ans,dist[1].len*minn);
}
void solve(int x)
{
for(int i=head[x];i;i=nxt[i])
if(clo[ver[i]]>=clo[x])
merge(x,ver[i]);
}
void dfs3(int x,int fro)
{
for(int i=head[x];i;i=nxt[i])
{
int to=ver[i];
if(to==fro) continue ;
dfs3(to,x);
}
dis[x]=dep[x]=dfn[x]=siz[x]=son[x]=topp[x]=head[x]=fa[x]=fat[x]=clo[x]=0;
pat[x].clear();
}
void work()
{
n=read();
for(int i=1;i<=n;i++)
{
clo[i]=read();
s[i]=(Node){i,clo[i]};
}
for(int i=1,x,y,val;i<n;i++)
{
x=read();
y=read();
val=read();
add_edge(x,y,val);
add_edge(y,x,val);
}
for(int i=1;i<=n;i++)
fa[i]=i;
sort(s+1,s+n+1,comp);
dfs1(1);
dfs2(1,1);
for(int i=1;i<=n;i++)
solve(s[i].id);
printf("%lld\n",ans);
dfs3(1,0);
tot=tim=ans=0;
}
signed main()
{
T=read();
while(T--) work();
return 0;
}

T3 玫瑰花精

解题思路

有一点像之前做过的 旅馆,但是不完全一样。

用线段树维护序列,主要维护 7 个值:lmx,ll,rr,rmx,llen,rlen,len

主要分为三个区间:

  1. 与整个区间的左边界相连的最长长度(llen)以及端点(ll)

  2. 同样的与整个区间的右边界相连的最长长度(rlen)以及端点(rr)

  3. 整个区间内的除了左右两个区间的所有未入住的区间中最长的长度(len)以及左右端点(lmx,rmx)

然后在维护时候主要对于上面的三个区间进行查找。

然后就是单点修改,区间查询,在搞的时候比较考验码力,具体实现细节见代码:

code

#include<bits/stdc++.h>
#define ls x<<1
#define rs x<<1|1
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch>'9'||ch<'0')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
const int N=2e5+10,M=1e6+10;
int n,m,s[M];
struct Segment_Tree
{
int lmx,ll,rr,rmx,llen,rlen,len;
}tre[N<<2];
inline void push_up(int x,int l,int r)
{
int mid=(l+r)>>1;
if( max( ((tre[rs].len+1)>>1),((tre[rs].llen+tre[ls].rlen+1)>>1) ) <= ((tre[ls].len+1)>>1) )
{
tre[x].len=tre[ls].len;
tre[x].lmx=tre[ls].lmx;
tre[x].rmx=tre[ls].rmx;
}
else if( max( ((tre[rs].len+1)>>1),((tre[ls].len+1)>>1) ) <= ((tre[rs].llen+tre[ls].rlen+1)>>1) )
{
tre[x].len=tre[rs].llen+tre[ls].rlen;
tre[x].lmx=tre[ls].rr;
tre[x].rmx=tre[rs].ll;
}
else if( max( ((tre[rs].llen+tre[ls].rlen+1)>>1),((tre[ls].len+1)>>1) ) <= ((tre[rs].len+1)>>1) )
{
tre[x].len=tre[rs].len;
tre[x].lmx=tre[rs].lmx;
tre[x].rmx=tre[rs].rmx;
}
tre[x].ll=tre[ls].ll;
tre[x].rr=tre[rs].rr;
tre[x].llen=tre[ls].llen;
tre[x].rlen=tre[rs].rlen;
if(tre[x].llen==mid-l+1)
{
tre[x].llen=mid-l+1+tre[rs].llen;
tre[x].ll=tre[rs].ll;
}
if(tre[x].rlen==r-mid)
{
tre[x].rlen=r-mid+tre[ls].rlen;
tre[x].rr=tre[ls].rr;
}
}
inline void build(int x,int l,int r)
{
tre[x].len=tre[x].llen=tre[x].rlen=r-l+1;//将可以入住的区间搞到最大
tre[x].lmx=tre[x].rr=l;//同时更新左右端点
tre[x].ll=tre[x].rmx=r;
if(l==r) return ;
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
}
inline void insert(int x,int l,int r,int pos)
{
if(l==r)
{
tre[x].len=tre[x].llen=tre[x].rlen=0;//标记入住
tre[x].lmx=tre[x].rr=pos+1;//三个区间错开
tre[x].ll=tre[x].rmx=pos-1;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) insert(ls,l,mid,pos);//向下递归
else insert(rs,mid+1,r,pos);
push_up(x,l,r);
}
inline void delate(int x,int l,int r,int pos)
{
if(l==r)
{
tre[x].len=tre[x].llen=tre[x].rlen=1;
tre[x].lmx=tre[x].rr=tre[x].ll=tre[x].rmx=pos;
return ;
}
int mid=(l+r)>>1;
if(pos<=mid) delate(ls,l,mid,pos);//递归更新
else delate(rs,mid+1,r,pos);
push_up(x,l,r);
}
inline void solve1(int pos)
{
int ans=(tre[1].lmx+tre[1].rmx)>>1;
if(tre[1].llen>=(tre[1].len+1)/2) ans=1;//只剩下1节点或者左侧的长度大于中间最大的一半
else if(tre[1].rlen>(tre[1].len+1)/2) ans=n;//只剩下n节点或者右侧更优
s[pos]=ans;
insert(1,1,n,ans);//记录并更新
printf("%d\n",ans);
}
inline void solve2(int pos)
{
delate(1,1,n,s[pos]);
}
signed main()
{
n=read();
m=read();
build(1,1,n);
while(m--)
{
int opt,pos;
opt=read();
pos=read();
if(opt==1) solve1(pos);
else solve2(pos);
}
return 0;
}

7.14考试总结(NOIP模拟15)[夜莺与玫瑰·影子·玫瑰花精]的更多相关文章

  1. 2021.9.14考试总结[NOIP模拟53]

    T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...

  2. 2021.8.14考试总结[NOIP模拟39]

    T1 打地鼠 全场就俩人没切,还有一个是忘关$freopen$了. $code:$ 1 #include<bits/stdc++.h> 2 #define rin register sig ...

  3. [考试总结]noip模拟15

    这次不咕了. 首先发现这套题目十分毒瘤, \(T1\) 就没有太大的思路. 结果最后也是暴力收场... 菜. \(T1\;60pts\) 暴力居然还是挺高的,\(T2\) 莽了一个随机化上去结果还是暴 ...

  4. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  5. 5.23考试总结(NOIP模拟2)

    5.23考试总结(NOIP模拟2) 洛谷题单 看第一题第一眼,不好打呀;看第一题样例又一眼,诶,我直接一手小阶乘走人 然后就急忙去干T2T3了 后来考完一看,只有\(T1\)骗到了\(15pts\)[ ...

  6. 5.22考试总结(NOIP模拟1)

    5.22考试总结(NOIP模拟1) 改题记录 T1 序列 题解 暴力思路很好想,分数也很好想\(QAQ\) (反正我只拿了5pts) 正解的话: 先用欧拉筛把1-n的素数筛出来 void get_Pr ...

  7. 2021.7.15考试总结[NOIP模拟16]

    ZJ模拟D2就是NB.. T1 Star Way To Heaven 谁能想到这竟是个最小生成树呢?(T1挂分100的高人JYF就在我身边 把上边界和下边界看成一个点和星星跑最小生成树,从上边界开始跑 ...

  8. 2021.9.17考试总结[NOIP模拟55]

    有的考试表面上自称NOIP模拟,背地里却是绍兴一中NOI模拟 吓得我直接文件打错 T1 Skip 设状态$f_i$为最后一次选$i$在$i$时的最优解.有$f_i=max_{j<i}[f_j+a ...

  9. [考试总结]noip模拟23

    因为考试过多,所以学校的博客就暂时咕掉了,放到家里来写 不过话说,vscode的markdown编辑器还是真的很好用 先把 \(noip\) 模拟 \(23\) 的总结写了吧.. 俗话说:" ...

  10. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

随机推荐

  1. 给picgo上传的图片加个水印

    之前给大家介绍了picgo和免费的图床神器.我们本可以开开心心的进行markdown写作了. 但是总是会有那么一些爬虫网站过来爬你的文章,还把你的文章标明是他们的原著.咋办呢?这里有一个好的办法就是把 ...

  2. canvas生成表单海报

    项目需要输入表单生成图片,可以使用下面方法生成海报,保存到手机,话不多说,上代码吧 HTML部分代码 <div class="dd"> <img src=&quo ...

  3. 物联网浏览器(IoTBrowser)-使用深度学习开发防浸水远程报警

    一.起因 新房子买在2楼,反水概率较大,加上无良开发商的劣质材料,就我所在楼栋已经发生几起反水事件,而且是高层反水,有几户重复出现反水,原因是管道中间有一个钢筋 :( 二.解决方案 1.水浸传感器+W ...

  4. 使用 Databricks 进行营销效果归因分析的应用实践【Databricks 数据洞察公开课】

    简介: 本文介绍如何使用Databricks进行广告效果归因分析,完成一站式的部署机器学习,包括数据ETL.数据校验.模型训练/评测/应用等全流程. 作者:冯加亮   阿里云开源大数据平台技术工程师 ...

  5. 网关流控利器:结合 AHAS 实现 Ingress/Nginx 流量控制

    ​简介:微服务的稳定性一直是开发者非常关注的话题.随着业务从单体架构向分布式架构演进以及部署方式的变化,服务之间的依赖关系变得越来越复杂,业务系统也面临着巨大的高可用挑战. 作者:涂鸦 微服务的稳定性 ...

  6. Dubbo-go v3.0 正式发布 ——打造国内一流开源 Go 服务框架

    ​简介:Dubbo-go 是常新的,每年都在不断进化.介绍 Dubbo-go 3.0 工作之前,先回顾其过往 6 年的发展历程,以明晰未来的方向. ​ 作者 | 李志信 来源 | 阿里技术公众号 作者 ...

  7. 函数计算 GB 镜像秒级启动:下一代软硬件架构协同优化揭秘

    ​简介:本文将介绍借助函数计算下一代 IaaS 底座神龙裸金属和安全容器,进一步降低绝对延迟且能够大幅降低冷启动频率. 作者:修踪 背景 函数计算在 2020 年 8 月创新地提供了容器镜像的函数部署 ...

  8. IIncrementalGenerator 解析 ValueTuple 的定义

    本文将告诉大家如何在分析器里面解析代码里面对于 ValueTuple 的定义,包括如何获取 ValueTuple 里面的 Item 的类型和命名 开始之前先创建一个用来被分析的项目,在这个项目里面定义 ...

  9. win10 uwp 使用 XamlTreeDump 获取 XAML 树元素内容

    本文来安利大家 XamlTreeDump 库,通过这个库可以将 XAML 树上的元素转换为 json 字符串,可以用来进行 UI 单元测试 开始之前先通过 NuGet 工具安装 XamlTreeDum ...

  10. 2.docker-compose安装prometheus

    一.docker-compose安装 前期准备 # docker配置文件 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json < ...