数据结构

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. 实用vim 130+命令

    基本命令 :e filename Open filename for edition :w Save file :q Exit Vim :q! Quit without saving :x Write ...

  2. 关于Oracle中sys、system和Scott用户下的数据库连接问题

    system默认:manager sys默认:change_on_install 使用SQL Plus登录数据库时,system使用密码manager可直接登录. 由于为自己的密码时更改过的,所以我的 ...

  3. 用 Core Animation 实现图片的碎片化

    用 Core Animation 实现图片的碎片化 参考书籍: 效果如下: 原理其实非常简单哦:). 1. 创建一个CALayer,使用其 contents 属性来装载一张图片(获取图片的CGImag ...

  4. [翻译] CBStoreHouseRefreshControl

    CBStoreHouseRefreshControl What is it? A fully customizable pull-to-refresh control for iOS inspired ...

  5. list(range())--------range创建一个list列表 遍历索引range(len()) 和 list(range())创建列表

    lst = list(range(15,26)) #注,list(range())用的是小括号哦print(lst)

  6. Java补充内容

      在第一个Java程序中已经提到一些基本的知识点,这里再补充几点. 1. 成员变量和局部变量的区别 成员变量:成员变量定义在类中,默认初始值为0,定义时可以不初始化,在整个类中可见. 局部变量:局部 ...

  7. ajax本地跨域请求以及解决方法

    什么是跨域?   我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景.所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源,只要没 ...

  8. 【原创】rabbitmq 学习

    rabbitmq 命令 1. 用户管理类命令: 该类别比较意图比较明显,详细查看官方文档.现做俩点说明: authenticate_user 此命令用于验证一个用户名和密码对不对,并没有什么用: se ...

  9. javascript 的MD5代码备份,跟java互通

    var MD5 = function (string) {                   function RotateLeft(lValue, iShiftBits) {            ...

  10. 将项目发布到Maven中央仓库的不完整纪要

    背景 有几个Utils性质的Jar需要跨项目引用,原本想部署私有Maven仓库,后来感觉太麻烦,索性直接发布到中央库,引用时也方便. 发布成功之后,觉得某些细节还是有必要记录一下. 资源 Sonaty ...