数据结构

Tags:Noip前的大抱佛脚

知识点及其应用

线段树

注意:空间开4倍

神奇标记

From8.26 Test_zsy(CPU监控)

如果一个点权为\(val\)的点被打上了\((a,b)\)标记,那么他的实际点权为\(max(a+val,b)\)

干啥滴?

标记不下放

  • 区间加标记不下放,维护区间max或者最大值

    方法是当前\(tag\)维护当前区域标记,\(t\)维护左右儿子的\(max+tag[now]\),并没有快多少,如果仍然忘记见提交记录

并查集

维护二分图

并查集每个点维护是否要改颜色,然后按秩合并/按大小合并即可

实际上可以说是用期望树高为\(logn\)的树形结构维护信息

维护后继位置

快速得到后继位置

  • [BZOJ2054]疯狂的馒头 维护数列的后继位置

    对一个数列进行\(10^7\)次区间覆盖,查询最终颜色。

    倒序做,每次做完一个区间把\([l,r]\)的并查集父亲指向\(r+1\),表示扫到该区间,要从\(r+1\)开始染色,这样就可以快速得到下一个染色的位置,复杂度为\(O(n)\)

  • [BZOJ2238]Mst 维护树形结构的后继位置

    对树上路径进行染色,查询最终颜色。

    路径拆成直上直下的两条,\(x,lca、y,lca\),于是每次弄完把\([x,lca]\)的并查集父亲指向\(fa[lca]\),就可以类似数列一样快速求得下一个位置了,复杂度为\(O(n)\)

对于所有的父子结构,一定都有父亲的优先级大于左右儿子的优先级

可并堆的可持久化

左偏树可持久化,每次合并两个堆,只需要给经过的\(log\)个结点复制一遍就好了

#define lc H[x].ch[0]
#define rc H[x].ch[1]
struct heap {int ch[2],dis;double w;}H[M];
int Merge(int x,int y)
{
if(!x||!y) return x+y;
H[++node]=H[x];x=node;
if(H[x].w>H[y].w) swap(x,y);
rc=Merge(rc,y);
if(H[lc].dis<H[rc].dis) swap(lc,rc);
H[x].dis=H[rc].dis+1;
return x;
}

这个可以用来完成\(k\)短路问题

dsu on tree

姑且叫它数据结构

方式&原理

步骤:

  • 先递归做轻儿子的答案,再递归做重儿子的答案
  • 暴力把当前结点的轻儿子扫一遍统计答案
  • 如果当前结点是递归下来的轻儿子,扫一遍把答案清空,否则不做处理

要求: 离线算法

复杂度: \(O(nlogn)\)

分析:只需要考虑每个点被扫的次数,树剖下来每个点到根的路径最多有\(log\)条链,每逢轻重链交替的时候就会暴力去扫,于是每个点最多只会被扫\(log\)次,复杂度得证

适用范围

适用一些子树信息不好统计的题,可以类比于树上莫队

  • 统计子树内数量最多的颜色的编号之和(Codeforces600E)
  • 统计子树内距离\(i\)点不超过\(k\)的点的颜色数/某权值之和(BZOJ4771七彩树离线版/[湖南集训]谈笑风生)

单调队列

尺取合法区间

这大概是一个常见用法。

丢一道萝卜的题:长度为\(n\)的序列,每个数是\([l[i],r[i]]\)内的一个值,求可能的LIS长度。

解法:当新加入的区间右端点大于前面所有区间的左端点时,产生矛盾。维护一个左端点的下降队列即可。

模板库

线段树

【模板】线段树 2

就是标记的优先顺序

const int N=1e5+10;
int n,m,t[N<<2],t1[N<<2],t2[N<<2],P;
void mul(int &x,int y) {x=1ll*x*y%P;}
void put(int x,int k,int op,int l,int r)
{
if(op==1) (t[x]+=1ll*(r-l+1)*k%P)%=P,(t2[x]+=k)%=P;
else mul(t[x],k),mul(t2[x],k),mul(t1[x],k);
}
void pushdown(int x,int l,int mid,int r)
{
int &s1=t1[x],&s2=t2[x];
if(s1!=1) put(x<<1,s1,2,l,mid),put(x<<1|1,s1,2,mid+1,r),s1=1;
if(s2!=0) put(x<<1,s2,1,l,mid),put(x<<1|1,s2,1,mid+1,r),s2=0;
}
void Add(int now,int l,int r,int gl,int gr,int op,int k)
{
if(l>=gl&&r<=gr) {put(now,k,op,l,r);return;}
int mid=(l+r)>>1;
pushdown(now,l,mid,r);
if(gl<=mid) Add(now<<1,l,mid,gl,gr,op,k);
if(gr>mid) Add(now<<1|1,mid+1,r,gl,gr,op,k);
t[now]=(t[now<<1]+t[now<<1|1])%P;
}
int Query(int now,int l,int r,int gl,int gr)
{
if(l>=gl&&r<=gr) return t[now];
int mid=(l+r)>>1,res=0;
pushdown(now,l,mid,r);
if(gl<=mid) res=Query(now<<1,l,mid,gl,gr);
if(gr>mid) res+=Query(now<<1|1,mid+1,r,gl,gr);
return res%P;
}
int main()
{
cin>>n>>m>>P;
for(int i=1;i<=n*4;i++) t1[i]=1;
for(int i=1,x;i<=n;i++) cin>>x,Add(1,1,n,i,i,1,x);
for(int i=1,x,y,k,op;i<=m;i++)
{
cin>>op>>x>>y;
if(op==1) cin>>k,Add(1,1,n,x,y,2,k);
if(op==2) cin>>k,Add(1,1,n,x,y,1,k);
if(op==3) cout<<Query(1,1,n,x,y)<<endl;
}
return 0;
}

点分治

一种分治思想,解决树上链的问题

const int N=21000;
struct edge{int next,to,w;}a[N];
int n,m,K[N],head[N],cnt,siz[N],rt,mx[N];
int sum,ans[N],vis[N],P[N],cc;
map<int,int> Map;
void Getroot(int x,int fr)
{
siz[x]=1;mx[x]=0;
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(R==fr||vis[R]) continue;
Getroot(R,x);siz[x]+=siz[R];
mx[x]=max(mx[x],siz[R]);
}
mx[x]=max(mx[x],sum-siz[x]);
if(mx[x]<mx[rt]) rt=x;
}
void calcsum(int x,int fr)
{
sum++;
for(int i=head[x];i;i=a[i].next)
if(a[i].to!=fr&&!vis[a[i].to]) calcsum(a[i].to,x);
}
void Getdis(int x,int d,int fr)
{
P[++cc]=d;
for(int i=head[x];i;i=a[i].next)
if(!vis[a[i].to]&&a[i].to!=fr)
Getdis(a[i].to,d+a[i].w,x);
}
void solve(int x)
{
rt=0;mx[0]=1e9;
sum=0;calcsum(x,0);
Getroot(x,0);
vis[x=rt]=1;Map.clear();
for(int i=head[x];i;i=a[i].next)
{
int R=a[i].to;if(vis[R]) continue;
cc=0;Getdis(R,a[i].w,x);
for(int j=1;j<=m;j++)
for(int w=1;w<=cc;w++)
if(Map.find(K[j]-P[w])!=Map.end()) ans[j]=1;
for(int w=1;w<=cc;w++) Map[P[w]]=1;
}
for(int j=1;j<=m;j++) if(Map.find(K[j])!=Map.end()) ans[j]=1;
for(int i=head[x];i;i=a[i].next)
if(!vis[a[i].to]) solve(a[i].to);
}
int main()
{
cin>>n>>m;
for(int i=1;i<n;i++)
{
int x,y,w;scanf("%d%d%d",&x,&y,&w);
a[++cnt]=(edge){head[x],y,w};head[x]=cnt;
a[++cnt]=(edge){head[y],x,w};head[y]=cnt;
}
for(int i=1;i<=m;i++) cin>>K[i];
solve(1);
for(int i=1;i<=m;i++) ans[i]?puts("AYE"):puts("NAY");
}

Noip前的大抱佛脚----数据结构的更多相关文章

  1. Noip前的大抱佛脚----文章索引

    Noip前的大抱佛脚----赛前任务 Noip前的大抱佛脚----考场配置 Noip前的大抱佛脚----数论 Noip前的大抱佛脚----图论 Noip前的大抱佛脚----动态规划 Noip前的大抱佛 ...

  2. Noip前的大抱佛脚----Noip真题复习

    Noip前的大抱佛脚----Noip真题复习 Tags: Noip前的大抱佛脚 Noip2010 题目不难,但是三个半小时的话要写四道题还是需要码力,不过按照现在的实力应该不出意外可以AK的. 机器翻 ...

  3. Noip前的大抱佛脚----图论

    目录 图论 知识点 二分图相关 DFS找环 并查集维护二分图 二分图匹配的不可行边 最小生成树相关 最短路树 最短路相关 负环 多源最短路 差分约束系统 01最短路 k短路 网络流 zkw费用流 做题 ...

  4. Noip前的大抱佛脚----字符串

    目录 字符串 经验 用FFT求解字符串匹配问题 两(多)串DP时状态合并 最长公共子序列转LIS 位运算最大值 挂链哈希 哈希处理回文串 树哈希 字符串模板库 KMP 最小循环表示 Mancher A ...

  5. Noip前的大抱佛脚----一些思路

    目录 一些思路 序列 函数问题 网格图 删除和询问 乘法问题 顺序问题 最值问题 研究成果 数论分块套数论分块的复杂度 一些思路 Tags:Noip前的大抱佛脚 序列 线段树(当然还要有主席树啊!) ...

  6. Noip前的大抱佛脚----数论

    目录 数论 知识点 Exgcd 逆元 gcd 欧拉函数\(\varphi(x)\) CRT&EXCRT BSGS&EXBSGS FFT/NTT/MTT/FWT 组合公式 斯特林数 卡塔 ...

  7. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  8. Noip前的大抱佛脚----根号对数算法

    根号算法 分块 数列分块入门九题(hzwer) 入门题1,2,3,4,5,7 问题:给一段区间打上标记后单点查询 解法:主要是每块维护一些标记,计算答案等,此类分块较为简单 注意:块大小一般为\(\s ...

  9. Noip前的大抱佛脚----奇技淫巧

    STL函数 set set查找前驱后继 multiset<int>::iterator iter; S.insert(x); iter=S.find(x);//返回迭代器 iter--;/ ...

随机推荐

  1. SQL索引未使用

    针对自己曾经经历过的一道面试题,那些情况不走索引,于是搜索网络和书籍的一些资料,整理如下: 1.查询谓词没有使用索引的主要边界,换句话说就是select *,可能会导致不走索引.比如,你查询的是SEL ...

  2. Struts-config.xml配置文件《action-mappings》元素的详解

    原文地址:http://blog.163.com/sara1124@126/blog/static/11291097020105125537114/ action-mappings 该元素用于将Act ...

  3. 引用js文件

    在子模板里引用js文件的时候,需要把相应的.js文件放到static目录下,如引用static/jQuery/index.js文件: {% extends "base.html" ...

  4. [沫沫金]JavaWeb企业信息系统,增加操作记录、数据库记录

    背景 系统出现数据莫名丢失,业务人员的反馈无法复现问题.纠结了很久,最终老板发话要记录操作,通过日志进行分析重现 环境 SSH框架 目标 1.记录访问了那个方法,使用的参数及返回的内容 2.记录新增. ...

  5. C++浅拷贝和深拷贝的区别

    C++浅拷贝和深拷贝的区别 2012-04-24 21:22 11454人阅读 评论(6) 收藏 举报 c++deleteclass编译器c c++默认的拷贝构造函数是浅拷贝 浅拷贝就是对象的数据成员 ...

  6. lambda表达式和groovy闭包的区别

    groovy定义的闭包是 Closure 的实例,lambda表达式只是在特定的接⼝或者抽象类的匿名实现,他们之间最主要区别闭包可以灵活的配置代理策略⽽labmda表达式不允许

  7. 最新版的Chrome 69.0 设置始终开启flash而不是先询问

    ## 69.0 之前的版本 ##   1.打开 chrome://settings/content/flash   2.禁止网站运行Flash -> 改为“Ask (Default)”   3. ...

  8. attr全选第三次失效

    一功能checkbox时隐时现,比如第一次打开有勾选,第n次打开可能就不选了. 经过偶层层抽次剥茧(da da jiang you),终于知道了原因:attr()在二次选中勾选框时,失效. 比如,如下 ...

  9. select、poll 和epoll区别

    阻塞 I/O(blocking IO) 当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据(对于网络IO来说,很多时候数据在一开始还没有到达.比如,还没有收到 ...

  10. http协议cookie结构分析

    Http协议中Cookie详细介绍   Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie.内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失 ...