线段树和其他

BIT

int tr[maxn];
void add(int x, int t) 
{
    for(int i=x; i<=n; i+=(i&(-i))) (tr[i]+=t)%=mod;
} 
int get(int x) 
{
    int ret=0;
    for(int i=x; i; i-=(i&(-i))) (ret+=tr[i])%=mod;
    return ret;
}

Segment_tree

struct segment_tree
{
	int x,y,z,w;
}tr[maxn*4];
void pushup(int k)
{
	tr[k].z=max(tr[lson].z,tr[rson].z);
}
void pushdown(int k)
{
	int w=tr[k].w;
	tr[lson].w+=w;
	tr[lson].z+=w;
	tr[rson].w+=w;
	tr[rson].z+=w;
	tr[k].w=0;
}
void build(int k,int l,int r)
{
	tr[k].w=0,tr[k].x=l,tr[k].y=r;
	if (l==r)
	{
		tr[k].z=c[l];
		return;
	}
	int mid=(l+r)/2;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(k);
}
void update(int k,int l,int r,int w)
{
	if (tr[k].y<l||tr[k].x>r) return;
	if (l<=tr[k].x&&tr[k].y<=r)
	{
		tr[k].w+=w;
		tr[k].z+=w;
		return;
	}
	if (tr[k].w) pushdown(k);
	update(lson,l,r,w);
	update(rson,l,r,w);
	pushup(k);
}
int query(int k,int l,int r)
{
	if (tr[k].y<l||tr[k].x>r) return 0;
	if (l<=tr[k].x&&tr[k].y<=r)
	{
		return tr[k].z;
	}
	if (tr[k].w) pushdown(k);
	return max(query(lson,l,r),query(rson,l,r));
}

一。线段树的operator + 直接合并的写法
二。树状数组加离散化


线段树(区间加区间统计)

#include<bits/stdc++.h>
#define FOR(i,x,y) for (int (i)=(x);(i)<=(y);(i)++)
#define PER(i,y,x) for (int (i)=(y);(i)>=(x);(i)--)
#define LL long long
#define lson k*2
#define rson k*2+1
#define mid ((l+r)>>1)
using namespace std;
const int maxn=200000+10;
struct tree
{
	int l,r,ll,rr,sz;
	LL tot;
} t[maxn*4];
int a[maxn];
tree operator + (tree a,tree b)
{
	tree c;
	c.l=a.l;
	c.r=b.r;
	c.sz=a.sz+b.sz;
	c.ll=(a.r<=b.l&&a.ll==a.sz)?(a.ll+b.ll):a.ll;
	c.rr=(a.r<=b.l&&b.rr==b.sz)?(a.rr+b.rr):b.rr;
	c.tot=a.tot+b.tot+((a.r<=b.l)?1ll*a.rr*b.ll:0ll);
	return c;
}

void build(int k,int l,int r)
{
	if (l==r)
	{
		t[k]=(tree){a[l],a[l],1,1,1,1ll};
		return;
	}
	build(lson,l,mid);
	build(rson,mid+1,r);
	t[k]=t[lson]+t[rson];
}
void update(int k,int l,int r,int x,int y)
{
	if (l==r)
	{
		t[k].l=y;
		t[k].r=y;
		return;
	}
	if (x<=mid) update(lson,l,mid,x,y);
	else if (x>mid) update(rson,mid+1,r,x,y);
	t[k]=t[lson]+t[rson];
}
tree query(int k,int l,int r,int ql,int qr)
{
	if (ql==l&&qr==r)
	{
		return t[k];
	}
	if (qr<=mid)
	{
		return query(lson,l,mid,ql,qr);
	}
	else if (ql>mid)
	{
		return query(rson,mid+1,r,ql,qr);
	}
	else return query(lson,l,mid,ql,mid)+query(rson,mid+1,r,mid+1,qr);
}
using namespace std;
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	FOR(i,1,n)
	{
		scanf("%d",&a[i]);
	}
	build(1,1,n);
	FOR(i,1,m)
	{
		int op,x,y;
		scanf("%d%d%d",&op,&x,&y);
		if (op==1)
		{
			update(1,1,n,x,y);
		}
		else 
		{
			tree tmp=query(1,1,n,x,y);
			LL ans=tmp.tot;
			printf("%lld\n",ans);
		}
	}
	
}

树状数组加离散化

//https://ac.nowcoder.com/acm/contest/3566/C
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+10;
const int mod=998244353;

int d[maxn];
int c[maxn];
int p[maxn];

int tot;
struct tree
{ 
	ll tr[maxn];
	void add(int x, ll t) 
	{
	    for(int i=x; i<=tot; i+=(i&(-i))) (tr[i]+=t)%=mod;
	}
	 
	ll get_sum(int x) 
	{
	    ll ret=0;
	    for(int i=x; i; i-=(i&(-i))) (ret+=tr[i])%=mod;
	    return ret;
	}
	 
}T[11];

int main()
{
    int n,m;
    cin>>n>>m;
    for (int i=1;i<=n;i++) 
    {
    	scanf("%d",&d[i]);//original array
    	c[++tot]=d[i];	//ordered array
	}
	c[++tot]=0;
	sort(c+1,c+1+tot);
	tot=unique(c+1,c+1+tot)-c-1;	

	
	for (int i=1;i<=n;i++)
	{		
		p[i]=lower_bound(c+1,c+1+tot,d[i])-c;//corresponding id.
	}	

	T[0].add(1,1);//little trick

	for (int i=1;i<=n;i++)	
	{
		int pos=p[i];
		for (int lay=1;lay<=m;lay++)
		{			
			ll num=T[lay-1].get_sum(pos-1);
			T[lay].add(pos,num);			
		}
	}	
	ll ans=T[m].get_sum(tot);
	cout<<ans<<endl;
}
posted on 2020-02-03 12:36  xlinsist  阅读(166)  评论(0)    收藏  举报