训练日记-多校
发布日期:2021-09-19 10:56:02 浏览次数:2 分类:技术文章

本文共 2565 字,大约阅读时间需要 8 分钟。

  首先是 Buildings

题目大概:

这道题是给出n,m,是一个矩形的大小,然后有一个地块x,y不能填矩形,问,如果用小矩形填满这个大矩形,使得最大的小矩形最小的填法,这个矩形大小是多少。

思路:

首先这个矩形一定是宽度为1,才最小而且符合题目要求。

这个题可以观察题目给出的样例,可以得知,就是求解   x,y   四周的这四个矩形填满   应该需要多大的矩形,取最小值。然后就是不管有没有这个x,y,直接用(n+1)/2,来整体求这个大矩形的最小值。

具体的如果n,m为奇数,而且x,y在中央,那么应该是n/2需要特判。

感想:

一般这种找规律的题,首先要从样例出发,找出规律,然后具体的特例需要自己造数据。

一般这种构造类型的题,需要自己取找构造的点,就是受题目限制很大的点,根据这些要点来构造,比如这里,x,y这个矩形的四周就是这个要点。

代码:

#include 
using namespace std;const int maxn=1e5+10;int n,m,x,y;int main(){ while(scanf("%d%d%d%d",&n,&m,&x,&y)!=EOF) { if(n>m) { swap(n,m); swap(x,y); } if(n==m&&n%2==1&&x==(n+1)/2&&y==(m+1)/2) { printf("%d\n",n/2); continue; } int mi_1=min(x-1,min(y,m-y+1)); int mi_2=min(n-x,min(y,m-y+1)); int ans=(n+1)/2; int sum=max(mi_1,max(mi_2,ans)); printf("%d\n",sum); } return 0;}

 

Gorgeous Sequence

题目大概:

给出n个数,然后给出3中操作

0  把 区间 l   r  的比v大的值改成v。

1 求区间  l  r  的最大值。

2 求区间  l  r 的和。

思路:

这个题的1  2操作都是线段树的基本操作,但是0操作有些复杂,如果直接修改,时间上会受不了。就采用了吉如一的线段树操作。维护最大值,次大值,最大值数量。这样在次大值<v<最大值的时候,就可以很快的把最大值都修改成 v,并用懒惰标记标记一下,这样维护后,对于修改后,最大值,次大值,最大值数量的维护,和的维护,都比较容易求解。

感想:

这样的维护,就把很多必须深入修改的东西,统一了起来。因为每次修改,修改到一定层数,一定会出现思路中讲到的修改方式,以此来进行懒惰修改,节约时间。这一点一定要借鉴学习,以后需要类似的问题,要转化成可以标记懒惰数组的形式。

代码:

#include 
using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn=1e6+10;int n,m;long long sum[maxn];int max_1[maxn],max_2[maxn];int maxsum[maxn];void pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; max_1[rt]=max(max_1[rt<<1],max_1[rt<<1|1]); maxsum[rt]=0; max_2[rt]=max(max_2[rt<<1],max_2[rt<<1|1]); if(max_1[rt]==max_1[rt<<1]) { maxsum[rt]+=maxsum[rt<<1]; } else max_2[rt]=max(max_1[rt<<1],max_2[rt]); if(max_1[rt]==max_1[rt<<1|1]) { maxsum[rt]+=maxsum[rt<<1|1]; } else max_2[rt]=max(max_1[rt<<1|1],max_2[rt]);}void pushdown(int rt){ if(max_1[rt]
<<1]) { sum[rt<<1]-=(long long)maxsum[rt<<1]*(max_1[rt<<1]-max_1[rt]); max_1[rt<<1]=max_1[rt]; } if(max_1[rt]
<<1|1]) { sum[rt<<1|1]-=(long long)maxsum[rt<<1|1]*(max_1[rt<<1|1]-max_1[rt]); max_1[rt<<1|1]=max_1[rt]; }}void build(int l,int r,int rt){ if(l==r) { scanf("%I64d",&sum[rt]); max_1[rt]=sum[rt]; max_2[rt]=-1; maxsum[rt]=1; return; } int m=(l+r)/2; build(lson); build(rson); pushup(rt);}void update(int L,int R,int v,int l,int r,int rt){ if(v>=max_1[rt])return; if(L<=l&&r<=R&&max_2[rt]
=L)update(L,R,v,lson); if(m

 

 

 

转载地址:https://blog.csdn.net/a1046765624/article/details/81088768 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:训练日记-多校
下一篇:训练日记

发表评论

最新留言

不错!
[***.144.177.141]2024年04月17日 07时06分53秒