暑期数据结构补充练习

想了想 还是得先把短板补起来

今天要是完成不了约定的任务那就明天别给自己放假了(笑

预期中今天下午放学之前要结束掉txt里的标星题   然后之后晚上要去补下字符串

另外markdown太蛋疼了QAQ 真不想用了


UOJ228 区间开根 

首先我们可能是想到转为减法 因为每次开根怎么想都不对吧

然后我们试一下 会发现开根取下整之后 一段连续的区间都会是一个值(这不废话吗……相当于把10000的区间压缩到100以内当然都是一个值啊

然后……然后我就很可耻地不记得了

我一开始的想法是记录最大和最小值 如果他们开方之后变为一个值,那么就直接进行区间覆盖(说着就否决了区间减法)

但是这样不仅会很不好写 而且当遇到我们下面提到的情况是没有很好的处理办法的_(:зゝ∠)_

然后又很可耻地不记得了 于是滚去看了一眼

发现别人都是当区间全为一个值的时候就打标记 (maya势能分析好可怕我真的不敢信这个复杂度啊

由于我记得有什么89899之类的数据能卡 所以就加了一句如果只差1而且开方后也只差1就打标记 然后就过去了

区间最值有助于判定一个区间有无修改的必要 而且经常出奇迹 要注意特殊数据


还有10题……瘫

bzoj4066 kdt

怀疑自己之前学的是假的

我以为kdt只能查询什么距离 因为它看上去复杂度很不对 而之所以能查询距离是因为有估价函数帮忙剪枝所以才行

结果被打脸了 原来kdt可以当二维线段树用啊(瘫

按照我的理解 为什么二维线段树空间大?因为有很多节点相当于是专门用于存和的

但kdt是一个点它既要代表一个实际存在的点 又要存下下面所包含的二叉子树信息

这也就是为什么build的时候是递归下去是l,mid-1 和 mid+1,r了

因为当前的mid已被且仅被当前点所记录

这也是为什么每次up都需要

t[x].mn[i]=t[x].mx[i]=t[x][i]; 以及 t[x].sum=t[l].sum+t[r].sum+t[x].w;

另外每次rebuild的范围应当是1-sz!

还记录一下很妙的写法

struct po{

    int d[2],l,r,w,sum,mn[2],mx[2];

    inline int& operator [] (int x) { return d[x]; }

    inline friend bool operator == (po a,po b) { return a[0]==b[0]&&a[1]==b[1]; }

    inline friend bool operator < (po a,po b) { return a[f]<b[f]; }

}p[N],t[N],h;

感觉这个结构体超好

还有一个问题就是我们是把单点加值变为了插入

那么判重的话就这么处理就好了

if (!x) {

    x=++sz;

    t[x][0]=t[x].mn[0]=t[x].mx[0]=h[0];

    t[x][1]=t[x].mn[1]=t[x].mx[1]=h[1];

}

if (t[x]==h) { t[x].w+=h.w,t[x].sum+=h.w; return ; }

   其中h为全局变量

另外我现在能理解为什么有人那么痴迷替罪羊了

暴力重构 非常优美

评论
© Utopia|Powered by LOFTER