• 线段树和其他


    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
    ",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;
    }
    
  • 相关阅读:
    【Java并发编程】之十一:线程间通信中notify通知的遗漏
    【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
    【Java并发编程】之九:死锁
    【Java并发编程】之八:多线程环境中安全使用集合API
    【Java并发编程】之七:使用synchronized获取互斥锁的几点说明
    多线程开发中遇到的问题
    Linux 设置IP,gate, 以及自动获取IP的方法
    C语言实现http get请求程序
    DHCP(动态主机配置协议)工作流程
    多线程程序中死锁的分析和解决方案
  • 原文地址:https://www.cnblogs.com/reshuffle/p/12255187.html
Copyright © 2020-2023  润新知