知识汇总2

树状数组

——高效求前缀和
(直接放板子了。。)

下标

点击查看代码
int lowbit(int x){
	return x&(-x);
} 

单点修改

点击查看代码
void add(int i,int k){
	while(i<=n){
		c[i]+=k;
		i+=lowbit(i);
	}
}

求和

点击查看代码
int getsum(int l){
	int res=0;
	while(l>0){
		res+=c[l];
		l-=lowbit(l);
	}
    return res;
}

线段树

比树状数组牛B的东西(是个二叉树)
记得预处理。。。

点击查看代码
int lid(int id){
    return id<<1;
}
int rid(int id){
    return id<<1|1;
}

建树

点击查看代码
void build(int id,int l,int r)
{
    m[id].lid=l;
    m[id].rid=r;
    if(l==r)
    {
        m[id].sum=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(lid(id),l,mid);
    build(rid(id),mid+1,r);
    m[id].sum=m[lid(id)].sum+m[rid(id)].sum;
}

下放标记

点击查看代码
void pushdown(int id)
{
    if(m[id].lazy&&m[id].lid!=m[id].rid)
    {
        m[lid(id)].lazy+=m[id].lazy;
        m[rid(id)].lazy+=m[id].lazy;
        m[lid(id)].sum+=m[id].lazy*(m[lid(id)].rid-m[lid(id)].lid+1);
        m[rid(id)].sum+=m[id].lazy*(m[rid(id)].rid-m[rid(id)].lid+1);
        m[id].lazy=0;
    }
}

单点修改

点击查看代码
void modify(int id,int x,int val)
{
    if(m[id].lid==m[id].rid)
    {
        m[id].sum+=val;
        return;
    }
    int mid=(m[id].lid+m[id].rid)>>1;
    modify(x<=mid?lid(id):rid(id),x,val);
    m[id].sum=m[lid(id)].sum+m[rid(id)].sum;
}

区间修改

点击查看代码
void add(int id,int l,int r,int s,int tt,int val)
{
    if(s>r||tt<l) return;
    if(s<=l&&tt>=r)
    {
        m[id].sum+=val*(r-l+1);
        m[id].lazy+=val;
        return;
    }
    int mid=(l+r)>>1;
    //pushdown(id);
    add(lid(id),l,mid,s,tt,val);
    add(rid(id),mid+1,r,s,tt,val);
    m[id].sum=m[lid(id)].sum+m[rid(id)].sum;
}

区间查询

点击查看代码
int find(int id,int l,int r,int s,int tt)
{
    if(s>r||tt<l) return 0;
    if(s<=l&&tt>=r) return m[id].sum;
    int mid=(l+r)>>1;
    //pushdown(id);
    return find(lid(id),l,mid,s,tt)+find(rid(id),mid+1,r,s,tt);
}

单调队列

最大值

点击查看代码
void getmax()
{
	int i,head=1,tail=0;
	for(i=1;i<m;i++)
	{
		while(head<=tail&&v[tail].x<=a[i]) tail--;\
		v[++tail].x=a[i],v[tail].y=i;
	}
	for(;i<=n;i++)
	{
		while(head<=tail&&v[tail].x<=a[i]) tail--;
		v[++tail].x=a[i],v[tail].y=i;
		while(v[head].y<i-m+1) head++;
		mx[i-m+1]=v[head].x;
	}
}

最小值

点击查看代码
void getmin()
{
	int i,head=1,tail=0;
	for(i=1;i<m;i++)
	{
		while(head<=tail&&v[tail].x>=a[i]) tail--;
		v[++tail].x=a[i],v[tail].y=i;
	}
	for(;i<=n;i++)
	{
		while(head<=tail&&v[tail].x>=a[i])tail--;
		v[++tail].x=a[i],v[tail].y=i;
		while(v[head].y<i+1-m) head++;
		mn[i-m+1]=v[head].x;
	}
}
~(单调栈就不放了,感觉没啥板子)~
posted @ 2024-02-19 17:15  _君の名は  阅读(13)  评论(0编辑  收藏  举报