首页 > 其他分享 >集训D1-3

集训D1-3

时间:2024-08-18 08:57:12浏览次数:14  
标签:pr return int void ls 集训 pl D1

集训

DAY1 搜索进阶

因此在学习的时候主要以代码实践为主(多做题)

深度优先搜索(dfs)基础

1.子集枚举
复杂度\(O(2^n)\)

2.排列枚举

复杂度\(O(n!)\)

Dfs的剪枝

1.优化搜索顺序

sort

枚举顺序(正/倒)

2.排除等效冗余

inline void dfs(int i,int len,int st){//P1120
	if(i==cnt+1)...
	if(len==tar)...
	for(int j=st/*限制单调*/;j<=n;j++){
		if(!vis[j]&&len+a[j]<=tar){
			...
			if(len==0||len+a[j]==tar)return;//排除等效冗余
			j=nxt[j];
		}

	}
}
int main(){
    ...
	nxt[n]=n;
	for(int i=n-1;i>=1;i--){//避免重复
		if(a[i]!=a[i+1])nxt[i]=i;
		else nxt[i]=nxt[i+1];
	}
	...
}

3.可行性剪枝(上下界剪枝) 当前分支必定失败

void dfs(int i,int lh,int lr,int sums,int sumv){//P1731 //P1025
	...
	if(sumv>=n)return;//可行性
	if(i*lr*lr*lh+sumv<n)return;
	if(i*2+sums>=ans)return;
	for(int j=lr-1;j>=i;j--)//上下界
		for(int k=lh-1;k>=i;k--)
			...
}

4.最优性剪枝 答案不会更优

if(...)return;//P10483 P1731

5.记忆化

迭代加深

搜索规模随搜索层数深入增长很快,且能够确保答案在较浅节点

思想:限制深度

bool dfs(int i){
	if(i==dep){
		return ...;
	}
	for...{if(...){return 1;}}
	return 0;
}
void solve(){
	dep=1;
	while(!dfs(1)){
		dep++;
	}
}//uva529

P1763

hack

双向搜索

具有明确的“初始状态”和“终止状态”

从初态和终态出发各搜一半状态,产生两个深度减半的状态空间,在中间交会、组合成最终答案。\(O(2^\frac{n}{2})\)

//CF888E U311043
void dfs1(int i)...
void dfs2(int i)...
void solve()...
int main(){
    dfs1();dfs2();solve();
}

广度优先搜索(BFS)基础

U311287

大模拟

struct传参太多会TLE

3维状态

U311289

多个源点同时入队

BFS变形

1.双端队列BFS(0/1bfs)

deque

0费入队首,1费入队尾

2.优先队列BFS

uva11367

定义状态\((city,cost,left)\)

dijkstra转移状态

优先队列使得\(cost\)最小

二维状态判重

void solve(){
	int c=read(),s=read()+1,e=read()+1;
	memset(vis,0,sizeof vis);
	memset(f,0x3f,sizeof(f));
	f[s][0]=0;
	priority_queue<node>q;
	q.push(node{s,0,0});
	while(!q.empty()){
		node now=q.top();
		q.pop();
		if(now.u==e){
			cout<<now.cot<<"\n";
			return;
		}
		if(vis[now.u][now.res])continue;
		else vis[now.u][now.res]=1;
		if(now.res<c&&f[now.u][now.res+1]>now.cot+val[now.u]){
			f[now.u][now.res+1]=now.cot+val[now.u];
			q.push(node{now.u,f[now.u][now.res+1],now.res+1});
		}
		for(int j=0;j<(int)a[now.u].size();j++){
			int v=a[now.u][j].v,w=a[now.u][j].w;
			if(now.res>=w&&f[v][now.res-w]>now.cot){
				f[v][now.res-w]=now.cot;
				q.push(node{v,f[v][now.res-w],now.res-w});
			}
		}
	}
	puts("impossible");
}

3.双向BFS

acwing177

大量细节

开两个队列q1,q2

每单位时间q1拓展三次,q2一次

若两者有相同可到达点即输出当前时间

拓展时打上第几次标记

拓展时打vis标记

多测清空

判段是否在鬼区内

void bfs(){
	int tim=0,pre=1,pre2=1;
	memset(vis,0,sizeof(vis));
	memset(vis2,0,sizeof(vis2));
	queue<node>q1;
	queue<node>q2;
	q1.push(node{bx,by,1});
	q2.push(node{gx,gy,1});
	while((!q1.empty())&&(!q2.empty())){
		tim++;
		for(int i=1;i<=3;i++){
			while(!q1.empty()&&q1.front().t==pre){
				node now=q1.front();
				q1.pop();
				if(!check(now.x,now.y,tim))continue;
				for(int j=0;j<4;j++){
					int tx=now.x+dx[j],ty=now.y+dy[j];
					if(tx>0&&tx<=n&&ty>0&&ty<=m&&check(tx,ty,tim)&&a[tx][ty]!='X'){
						if(vis2[tx][ty]){
							cout<<tim<<"\n";
							return;
						}
						if(vis[tx][ty])continue;
						else vis[tx][ty]=1;
						q1.push(node{tx,ty,pre+1});
					}
				}
			}
			pre++;
		}	
		while(!q2.empty()&&q2.front().t==pre2){
			node now=q2.front();
			q2.pop();
			if(!check(now.x,now.y,tim))continue;
			for(int j=0;j<4;j++){
				int tx=now.x+dx[j],ty=now.y+dy[j];
				if(tx>0&&tx<=n&&ty>0&&ty<=m&&check(tx,ty,tim)&&a[tx][ty]!='X'){
					if(vis[tx][ty]){
						cout<<tim<<"\n";
						return;
					}
					if(vis2[tx][ty])continue;
					else vis2[tx][ty]=1;
					q2.push(node{tx,ty,pre2+1});
				}
			}	
		}
		pre2++;
	}
	puts("-1");
}

DAY2-3 数据结构提高

单调栈

//P5788
stack<int>st;
for(int i=1;i<=n;i++){
    while(!st.empty()&&h[i]>h[st.top()])st.pop();
    st.push(i);
}
while(!st.empty())st.pop();

分治+单调栈

某计蒜客题

P1823

在单调栈内二分

SP1805

经典

单调队列

deque<int>q;
for(int i=1;i<=n;i++){
    while(!q.empty()&&q.front()<i-m)q.pop_front();
	...
    while(!q.empty()&&a[q.back()]>=a[i])q.pop_back();
    q.push_back(i);
}//P1440

P2216

二维

void push(int x){//P3378
	heap[++len]=x;
	int i=len;
	while(i>1&&heap[i/2]>heap[i]){
		swap(heap[i/2],heap[i]);
		i=i/2;
	}
}
void pop(){
	heap[1]=heap[len--];
	int i=1;
	while(i*2<=len){
		int son=i*2;
		if(son+1<=len&&heap[son]>heap[son+1])son++;
		if(heap[son]<heap[i]){
			swap(heap[son],heap[i]);
			i=son;
		}else break;
	}
}
int ask(){return heap[1];}

左偏树

\(dist\)定义:一个节点到子树中最近的外节点所经过的边的数量,\(dist[0]=-1\)

维护\(dist\)以维护左偏性质

左偏树的深度没有保证

int find(int i){return f[i]==i?i:f[i]=find(f[i]);}//P3377
int merge(int i,int j){
	if(!i||!j)return i|j;//节点为0
	if(a[j].val<a[i].val)swap(i,j);//维护堆
	a[i].rs=merge(a[i].rs,j);//递归合并右子和另一个堆
	if(a[a[i].rs].dist>a[a[i].ls].dist)swap(a[i].ls,a[i].rs);//维护左偏
	a[i].dist=a[a[i].rs].dist+1;//维护dist
	return i;//返回节点
}
void init(){
    a[0].dist=-1;
		scanf("%d",&a[i].val);
		a[i].id=f[i]=i;
		a[i].ls=a[i].rs=a[i].dist=a[i].dead=0;
}
int main(){
	//合并 插入
        if(a[x].dead||a[y].dead)continue;
        int fx=find(x),fy=find(y);
        if(fx!=fy)f[fx]=f[fy]=merge(fx,fy);
	//删除根
        if(a[x].dead)continue;
        int fx=find(x);a[fx].dead=1;
        f[fx]=f[a[fx].ls]=f[a[fx].rs]=merge(a[fx].ls,a[fx].rs);
}

P4331

基础 STL

注意:

1.区间左闭右开 [,)

2.deque->MLE

pair

默认排序先first后second

vector

t.emplace_back()//新插入方式
t.resize()//重置大小
//定点插入删除元素
v.insert(a.begin()+i,j)//在v的第i个元素位置插入j(从0开始)
v.erase(a.begin(),a.begin()+i)//删除 v 的 第0~第i-1个元素

set (multiset)

去重(不去重)

s.erase(pos)//删除pos迭代器所指向的元素,返回下一个迭代器的位置
s.erase(x)//为删除set中值为x的元素
//注意:multiset执行该操作会删除所有=x的元素,如果只想删除一个则应用s.erase(s.find(x))
s.find(x)//查找 x 元素是否存在,如果存在返回该元素的迭代器,若不存在,返回s.end(),用法 auto pos=s.find(x)
s.count(x)//查找 x 元素的个数,用于 multiset,复杂度很高,为O(ans+logn)
s.lower_bound(x)//返回第一个 >= x 的元素的迭代器
s.upper_bound(x)//返回第一个 > x 的元素的迭代器

nth_element()

平均O(n)的时间复杂度,将数组中第k小的元素放到第k个位置上,同时保证左边元素全部小于它,右边元素全部大于它。

//用法 (a数组下标从1开始,将第i小的元素放到第i个位置)
nth_element(a+1,a+i,a+n+1,cmp);

lower_bound()

返回第一个>=x位置下标

upper_bound()

返回第一个>x位置下标

使用前保证单调性!sort

//用法
int p=lower_bound(a+1,a+n+1,x,cmp);

map

map<T,T>mp;//T必须已定义大小比较

bitset

优化传递闭包,背包 \(O(\frac{n}{w})\)

bitset<size>b;

树状数组

1.单点修改,区间查询

int lowbit(int i){return i&(-i);}//P3374
int sum(int i){
	int ret=0;
	while(i){
		ret+=c[i];
		i-=lowbit(i);
	}
	return ans;
}
void add(int i,int val){
	while(i<=n){
		c[i]+=val;
		i+=lowbit(i);
	}
}

2.区间修改,单点查询

维护原序列的差分序列

线段树

注意:四倍空间

void pushup(int p){
	...
}
void update(int p,int pl,int pr,...){
	if(pl==pr){
		...
        return;
	}
	if(...)update(ls,pl,mid,...);
	if(...)update(rs,mid+1,pr,...);
	pushup(p);
}
int query(int l,int r,int p,int pl,int pr){
	if(l<=pl&&pr<=r){
		return ...;
	}
	int ret=0;
	if(l<=mid)...
	if(r>mid)...
	return ret;
}

P4513

经典

LOJ6029

除法转化为减法,暴力更新

void updatediv(int l,int r,int p,int pl,int pr,int k){
	if(l<=pl&&pr<=r){
		ll n1=floor(1.0*t[p].maxn/k)-t[p].maxn;
		ll n2=floor(1.0*t[p].minn/k)-t[p].minn;
		if(pl==pr){
			t[p].sum=t[p].maxn=t[p].minn=floor(1.0*t[p].minn/k);
		}else if(n1==n2){
			t[p].tag+=n1;
			t[p].maxn+=n1;
			t[p].minn+=n1;
			t[p].sum+=n1*(pr-pl+1);
		}else{
			pushdown(p,pl,pr);
			updatediv(l,r,ls,pl,mid,k);
			updatediv(l,r,rs,mid+1,pr,k);
			pushup(p);
		}
		return;
	}
	pushdown(p,pl,pr);
	if(l<=mid)updatediv(l,r,ls,pl,mid,k);
	if(r>mid)updatediv(l,r,rs,mid+1,pr,k);
	pushup(p);
}

不开long long见祖宗

P3369

值域线段树&动态开点线段树

void pushup(int p){
	val[p]=val[ls]+val[rs];
}
void add(int &p,int pl,int pr,int pos,int k){//数pos的个数增加k
	if(!p)p=++cnt;
	if(pl==pr){
		val[p]+=k;
		return;
	}
	if(pos<=mid)add(ls,pl,mid,pos,k);
	else if(pos>mid)add(rs,mid+1,pr,pos,k);
	pushup(p);
}
int query(int l,int r,int p,int pl,int pr){//返回[l,r]数的个数
	if(!p)return 0;
	if(l<=pl&&pr<=r)return val[p];
	int ans=0;
	if(l<=mid)ans+=query(l,r,ls,pl,mid);
	if(r>mid)ans+=query(l,r,rs,mid+1,pr);
	return ans;
}
int getrank(int k,int p,int pl,int pr){//查询第k大的数
	if(pl==pr)return pl;
	if(val[ls]>=k)return getrank(k,ls,pl,mid);
	else return getrank(k-val[ls],rs,mid+1,pr);
}
//插入一个数x
add(rt,-lim,lim,x,1);
//删除一个数x(若有多个相同的数,应只删除一个)
add(rt,-lim,lim,x,-1);
//定义排名为比当前数小的数的个数+1,查询x的排名
query(-lim,x-1,rt,-lim,lim)+1
//查询数据结构中排名为x的数
getrank(x,rt,-lim,lim)
//求x的前驱(前驱定义为小于x,且最大的数)
int rk=query(-lim,x-1,rt,-lim,lim);
getrank(rk,rt,-lim,lim)
//求x的后继(后继定义为大于x,且最小的数)
int rk=query(-lim,x,rt,-lim,lim)+1;
getrank(rk,rt,-lim,lim)

P4198

序列\(a\),可修改,查询满足\({\forall}j{\in}[1,i-1],a[i]>a[j]\)的\(i\)个数

复杂度\(O(nlog^2n)\)

int query(int p,int pl,int pr,double K){//返回p节点内>k的个数
	if(pl==pr){
		return t[p].maxn>K;
	}
	if(t[ls].maxn>K)return query(ls,pl,mid,K)+t[p].len-t[ls].len;//递归左子+右子贡献
	else return query(rs,mid+1,pr,K);//左子无贡献,递归右子
}
void pushup(int p,int pl,int pr){
	t[p].maxn=max(t[ls].maxn,t[rs].maxn);
	t[p].len=t[ls].len+query(rs,mid+1,pr,t[ls].maxn);//左子不受影响+右子>左子最大值
}
void update(int pos,int p,int pl,int pr,double K){
	if(pl==pr){
		t[p].len=1;
		t[p].maxn=K;
		return;
	}
	if(pos<=mid)update(pos,ls,pl,mid,K);
	else update(pos,rs,mid+1,pr,K);
	pushup(p,pl,pr);
}
update(x,1,1,n,tmp);
t[1].len

P4556

值域线段树+树上差分+线段树合并

int merge(int p,int i,int pl,int pr){//合并
	if(!p||!i)return p|i;
	if(pl==pr){
		...
		return p;
	}
    //合并左右子树
	ls=ch[i][0]=merge(ls,ch[i][0],pl,mid);
	rs=ch[i][1]=merge(rs,ch[i][1],mid+1,pr);
	pushup(p);
	return p;
}
void getans(int i,int fa){//自下而上合并
	for(int j=0;j<a[i].size();j++){
		int v=a[i][j];
		if(v!=fa){
			getans(v,i);
			rt[i]=rt[v]=merge(rt[i],rt[v],1,1e5);//更改根节点
		}
	}
    //统计答案
	ans[i]=maxn[rt[i]];
	if(!sum[rt[i]])ans[i]=0;//特判
}

P4197

线段树合并

在每个点建一颗线段树,加入离散化后的点权

离线询问,按\(x\)排序

将边按边权排序,枚举每个询问,加边,合并线段树

注意数组大小

输出回车

CF786B

线段树优化建图

一棵入树,一棵出树,节点标号偏移\(D\)

\(D\)由数据范围确定

void build(int p,int pl,int pr){
	if(pl==pr){
		a[pl]=p;//获取节点i对应的树上节点a[i]
		return;
	}
    //出树向父节点连边
	e[ls+D].push_back(edge{p+D,0});
	e[rs+D].push_back(edge{p+D,0});
	//入树向子节点连边
    e[p].push_back(edge{ls,0});
	e[p].push_back(edge{rs,0});
	build(ls,pl,mid);
	build(rs,mid+1,pr);
}
void connect(int l,int r,int v,ll w,int p,int pl,int pr,int op){
	if(l<=pl&&pr<=r){
        //出树向入树连边
		if(op)e[p+D].push_back(edge{a[v],w});
		else e[a[v]/*注意转换*/+D].push_back(edge{p,w});
		return;
	}
	if(l<=mid)connect(l,r,v,w,ls,pl,mid,op);
	if(r>mid)connect(l,r,v,w,rs,mid+1,pr,op);
}
void init(){
    build(1,1,n);
	for(int i=1;i<=n;i++){
        //出树和入树的叶子节点是同一节点
		e[a[i]/*注意转换*/].push_back(edge{a[i]/*注意转换*/+D,0});
		e[a[i]/*注意转换*/+D].push_back(edge{a[i]/*注意转换*/,0});
	}
}
//单点
e[a[v]+D].push_back(edge{a[u],w});
//单点->区间&区间->单点
connect(l,r,v,w,1,1,n,op%2);
//注意图上节点向树上节点编号转换 i->a[i] 在dijkstra时以及答案统计和输出时

trie

P5283 摆

P4551

void insert(int s){
	int p=0;
	for(int i=(1<<30);i>0;i>>=1){
		bool t=s&i;//注意bool
		if(!ch[p][t])ch[p][t]=++id;
		p=ch[p][t];
	}
	cnt[p]++;
}
int ask(int s){
	int p=0,ret=0;
	for(int i=(1<<30);i>0;i>>=1){
		bool t=s&i;
		if(ch[p][!t]){
			ret+=i;
			p=ch[p][!t];
		}else p=ch[p][t];
	}
	return ret;
}
//d[i]为树上异或前缀
insert(d[i]);
ans=max(ans,ask(d[i]));

标签:pr,return,int,void,ls,集训,pl,D1
From: https://www.cnblogs.com/wertyuio1/p/18365255

相关文章

  • 集训D4-5
    DAT4-5图论最短路性质记\(dis[u]\)代表从源点走到u的最短路长度1.贪心性:源点到任意一个点最短路上的每一步都是一个最短路2.存在性:两个点之间的最短路有可能不存在。(源点存在一个到达该点且经过一个负环的路径/图不连通)3.三角形不等式:对于一条边\(u\stackrel{w}{\to}v\),一......
  • D1-H Tinalinux 开发板 挂载U盘
    将U盘格式化成NFS格式 插入U盘到开发板HostUSB,会显示信息[4060.109026]usb1-1:USBdisconnect,devicenumber7[4139.330081]sunxi-ehci4200000.ehci1-controller:ehci_irq:highspeeddeviceconnect[4139.600007]usb1-1:newhigh-speedUSBdevicenumber8......
  • 『模拟赛』暑假集训CSP提高模拟23
    Rank玩蓝图玩的A.进击的巨人(原题都是牛客的,没号所以不挂了)赛事看到概率期望一眼润,但是又可惜暴力分,遂打(最坏情况下)\(\mathcal{O(n^2)}\)暴力,结果很给力啊,调出来小样例后大样例嗖的一下就过了,惊喜了属于是,喜提100pts。事实上跑这么快是因为0的数量很平均,导致复杂度大......
  • [赛记] 暑假集训CSP提高模拟22 23
    连通块66pts老套路,删边改加边;但改完以后不知道怎么求最长路径了,当时也想到了维护直径,但不知道咋干;具体地,用并查集维护连通性,每次合并时需要维护新的直径,不难发现,新的直径的两个端点一定在原来的两个直径的四个端点中选;于是只有六种情况,枚举一下即可;我们要直径有啥用呢?当我们......
  • D1-H 哪吒 HDMI测试
    使用镜像D1-H哪吒HDMI测试固件https://www.aw-ol.com/downloads/resources/22输入命令切换到HDMI输出:cd/sys/kernel/debug/dispdbgechodisp0>name;echoswitch1>command;echo410000x40x1010008>param;echo1>start;测试显示colorbar:echo1>/sys/cl......
  • 2024.8.16 总结(集训)
    今天是[whx](?)巨佬来给我们讲数论,大概是狄利克雷卷积、莫比乌斯反演、杜教筛、PN筛这条线路。虽然我很喜欢莫反,之前写了一些莫反题,但今天还是很有收获。对整除分块、杜教筛的理解更深刻了(关于整除分块为什么是\(O(\sqrtn)\)的、杜教筛的本质)。明白了\(\mu\)适合容斥。见到......
  • 2024 暑假平邑一中集训整合(下)
    Day10考试T3形式化题意,给定\(n,m\),求\(\sum^n_{i=1}\sum^m_{j=1}\displaystyle\begin{pmatrix}n\\i\\\end{pmatrix}\displaystyle\begin{pmatrix}i\\j\\\end{pmatrix}\)推式子:\[\sum^n_{i=1}\sum^m_{j=1}\displaystyle\begin{pmatrix}n\\i......
  • 『模拟赛』暑假集训CSP提高模拟22
    Rank非常好重测,使我Rank--A.法阵原[CF1503E]2-Coloring出题人注:原题3100,张口放T1一眼高难度题,于是果断开始暴力打表,但我的打表程序十分暴力,跑\(n=6,m=9\)的点就已经开始硬控了,遂只拿到30pts。打表就不用放了吧,等我咕咕正解。B.连通块同[yLCPC2024]F.PANDORA......
  • 豪威最新发布的 OX08D10 2.1UM像素尺寸图像传感器
    【国产传感器与高通携手,开发智能驾驶汽车视觉保障】国产厂商豪威最新宣布,其采用TheiaCel技术的OX08D10图像传感器已兼容高通SnapdragonDigitalChassis(骁龙数字底盘)。该传感器在各种照明条件下都能提供优秀的成像质量,为汽车带来稳定的视觉保障。豪威集团汽车产品市场经理Pau......
  • 暑假集训csp提高模拟22
    赛时rank24,T120,T266,T30,T410T1*3100,T2逆天trick,T3抽象题面,T4也挺抽象反正是暴力专场T1、T3、T4太抽象了,不会,直接挂的官方题解可能模拟赛难度为强紫+弱紫/强蓝+紫+紫?调了一个最简单的T2,学习一下这个trick。我树套树还没写玩呢T1法阵2-Coloring原题3100,张口放......