zoukankan      html  css  js  c++  java
  • NOIp 数据结构

    一、树状数组

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=500005;
    #define ll long long
    ll n,m,opt,b,c,tmp;
    ll a[MAXN];
    ll lowbit(ll x){return x&-x;}
    ll que(ll x){
    	ll ret=0;
    	for(ll i=x;i>0;i-=lowbit(i))
    	    ret+=a[i];
    	return ret;
    }
    void add(ll x,ll k){
    	for(ll i=x;i<=n;i+=lowbit(i))
    	    a[i]+=k;
    }
    int main(){
    	scanf("%lld%lld",&n,&m);
    	for(ll i=1;i<=n;i++){
    		scanf("%lld",&tmp);
    		add(i,tmp);
    	}	
    	for(ll i=1;i<=m;i++){
    		cin>>opt>>b>>c;
    		if(opt==1){
    			add(b,c);
    		}
    		if(opt==2){
    			printf("%lld
    ",que(c)-que(b-1));
    		}
    	}
    	return 0;
    }
    

    二、树状数组+差分

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=500005;
    #define ll long long
    int n,m,opt;
    ll tmp[MAXN],a[MAXN],b,c,d;
    ll lowbit(ll x){return x&-x;}
    void add(ll x,ll k){
    	for(int i=x;i<=n;i+=lowbit(i))
    	    a[i]+=k;
    }
    ll que(ll x){
    	ll ret=0;
    	for(int i=x;i>0;i-=lowbit(i))
    	    ret+=a[i];
    	return ret;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)scanf("%lld",&tmp[i]);
    	for(int i=1;i<=m;i++){
    		cin>>opt;
    		if(opt==1){
    			cin>>b>>c>>d;
    			add(b,d);
    			add(c+1,-d);
    		}
    		if(opt==2){
    			cin>>b;
    			printf("%lld
    ",que(b)+tmp[b]);
    		}
    	}
    	return 0;
    }
    

    三、线段树(区间加,区间乘,区间求和)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=500005;
    #define ll long long
    ll t1[MAXN],t2[MAXN],a[MAXN],sum[MAXN];
    int n,m,opt;
    ll p,b,c,d;
    ll lc(ll x){return x<<1;}
    ll rc(ll x){return x<<1|1;}
    void pushup(ll x){sum[x]=(sum[lc(x)]+sum[rc(x)])%p;}
    void pushdown(ll l,ll r,ll x){
    	ll c1=lc(x),c2=rc(x),mid=(l+r)>>1;
    	t1[c1]=t1[c1]*t2[x]%p;
    	t1[c2]=t1[c2]*t2[x]%p;
    	t2[c1]=t2[c1]*t2[x]%p;
    	t2[c2]=t2[c2]*t2[x]%p;
    	sum[c1]=sum[c1]*t2[x]%p;
    	sum[c2]=sum[c2]*t2[x]%p;
    	t2[x]=1;
    	t1[c1]=(t1[c1]+t1[x])%p;
    	t1[c2]=(t1[c2]+t1[x])%p;
    	sum[c1]=(sum[c1]+(mid-l+1)*t1[x])%p;
    	sum[c2]=(sum[c2]+(r-mid)*t1[x])%p;
    	t1[x]=0;
    }
    void build(ll l,ll r,ll x){
    	t1[x]=0;t2[x]=1;
    	if(l==r){
    		sum[x]=a[l];
    		return;
    	}
    	ll mid=(l+r)>>1;
    	build(l,mid,lc(x));
    	build(mid+1,r,rc(x));
    	pushup(x);
    }
    void mul(ll L,ll R,ll l,ll r,ll x,ll k){
    	if(L<=l&&r<=R){
    		t2[x]=t2[x]*k%p;
    		t1[x]=t1[x]*k%p;
    		sum[x]=sum[x]*k%p;
    		return;
    	}
    	ll mid=(l+r)>>1;
    	if(t1[x]!=0||t2[x]!=1)pushdown(l,r,x);
    	if(L<=mid)mul(L,R,l,mid,lc(x),k);
    	if(mid<R)mul(L,R,mid+1,r,rc(x),k);
    	pushup(x);
    }
    void add(ll L,ll R,ll l,ll r,ll x,ll k){
    	if(L<=l&&r<=R){
    		t1[x]=(t1[x]+k)%p;
    		sum[x]=(sum[x]+(r-l+1)*k)%p;
    		return;
    	}
    	ll mid=(l+r)>>1;
    	if(t1[x]!=0||t2[x]!=1)pushdown(l,r,x);
    	if(L<=mid)add(L,R,l,mid,lc(x),k);
    	if(mid<R)add(L,R,mid+1,r,rc(x),k);
    	pushup(x);
    }
    ll que(ll L,ll R,ll l,ll r,ll x){
    	ll ret=0;
    	if(L<=l&&r<=R){
    		return sum[x]%p;
    	}
    	if(t1[x]!=0||t2[x]!=1)pushdown(l,r,x);
    	ll mid=(l+r)>>1;
    	if(L<=mid)ret+=que(L,R,l,mid,lc(x));
    	if(mid<R)ret+=que(L,R,mid+1,r,rc(x));
    	return ret%p;
    }
    
    int main(){
    	scanf("%d%d%lld",&n,&m,&p);
    	for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    	build(1,n,1);
    	for(int i=1;i<=m;i++){
    		scanf("%d",&opt);
    		if(opt==1){
    			scanf("%lld%lld%lld",&b,&c,&d);
    			mul(b,c,1,n,1,d);
    		}
    		if(opt==2){
    			scanf("%lld%lld%lld",&b,&c,&d);
    			add(b,c,1,n,1,d);
    		}
    		if(opt==3){
    			scanf("%lld%lld",&b,&c);
    			printf("%lld
    ",que(b,c,1,n,1));
    		}
    	}
    	return 0;
    }
    

    四、单调队列

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=1000005;
    int n,k,a[MAXN],q[MAXN],p[MAXN];
    void getmax(){
    	int head=1,tail=0;
    	for(int i=1;i<=n;i++){
    		while(head<=tail&&q[tail]<=a[i])tail--;
    		q[++tail]=a[i];p[tail]=i;
    		while(p[head]<=i-k)head++;
    		if(i>=k)printf("%d ",q[head]);
    	}
    }
    void getmin(){
    	int head=1,tail=0;
    	for(int i=1;i<=n;i++){
    		while(head<=tail&&q[tail]>=a[i])tail--;
    		q[++tail]=a[i];p[tail]=i;
    		while(p[head]<=i-k)head++;
    		if(i>=k)printf("%d ",q[head]);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    	getmin();
    	printf("
    ");
    	getmax();
    	printf("
    ");
    	return 0;
    }
    

    五、Splay

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN=500100;
    int rt,n,tot;
    struct node{
        int ch[2],fa,size,to,sum; 
    }a[MAXN];
    struct Splay{
        void pushup(int u){a[u].sum=a[a[u].ch[0]].sum+a[a[u].ch[1]].sum+a[u].size;}
        inline bool getwh(int u){return a[a[u].fa].ch[0]==u?0:1;}
        inline void rotate(int u){
        int f=a[u].fa,gr=a[f].fa;//节点号 
        int wh=getwh(u);
        a[u].fa=gr;a[gr].ch[getwh(f)]=u;
        a[a[u].ch[wh^1]].fa=f;
        a[f].ch[wh]=a[u].ch[wh^1];
        a[f].fa=u;
        a[u].ch[wh^1]=f;
        pushup(f);pushup(u);
        }
        inline void splay(int u,int tar){
            while(a[u].fa!=tar){
                if(a[a[u].fa].fa!=tar){
                    if(getwh(u)==getwh(a[u].fa))
                    rotate(a[u].fa);
                    else rotate(u);
                }rotate(u);
            }
            if(!tar)rt=u;
        }
        void ins(int x){
           int u=rt,f=0;
           while(u&&a[u].to!=x){
                f=u;
                u=a[u].ch[x>a[u].to];
           }
           if(u) a[u].size++;
           else{
               u=++tot;
               if(f)a[f].ch[x>a[f].to]=u;
               a[tot].fa=f;
               a[tot].to=x;
               a[tot].size=1; 
               a[tot].sum=1;
           }
           splay(u,0);
        }
        void find(int x){
           int u=rt;
           if(!u)return;
           while(a[u].ch[x>a[u].to]&&x!=a[u].to)
              u=a[u].ch[x>a[u].to]; 
           splay(u,0);
        }
        int nxt(int x,int f){
           find(x); 
           int u=rt;
           if((a[u].to>x&&f)||(a[u].to<x&&!f))return u;
           u=a[u].ch[f];
           while(a[u].ch[f^1])u=a[u].ch[f^1];
           return u;
        }
        void del(int x){
           int last=nxt(x,0);
           int next=nxt(x,1);
           splay(last,0);splay(next,last);
           int del=a[next].ch[0];
           if(a[del].size>1){
                a[del].size--;
                splay(del,0);
           }
           else a[next].ch[0]=0; 
        }
        int findkth(int x){
           int o=rt;
           if(a[o].sum<x)
              return 0;
           while(1){
                int y=a[o].ch[0];
                if(x>a[y].sum+a[o].size){
                         x-=a[y].sum+a[o].size;
                     o=a[o].ch[1];
                }
                else if(a[y].sum>=x)
                       o=y;       
                else
                    return a[o].to;
           }
        }
    }splay;
    int main(){
       splay.ins(-2147483647);
       splay.ins(2147483647);
       cin>>n;
       while(n--){
         int opt,x;cin>>opt>>x;
         if(opt==1)
            splay.ins(x);
         if(opt==2)
            splay.del(x);
         if(opt==3){
              splay.find(x);
              printf("%d
    ",a[a[rt].ch[0]].sum);
         }
         if(opt==4)
              printf("%d
    ",splay.findkth(x+1));
         if(opt==5)
            printf("%d
    ",a[splay.nxt(x,0)].to);
         if(opt==6)
            printf("%d
    ",a[splay.nxt(x,1)].to);
       }
       return 0;
    }
    
  • 相关阅读:
    AD19覆铜与边框间距设置方法
    PADS规则设计-对某一网络/元件单独设置规则
    uC/OSii之任务划分
    对于单片机工程.h头文件的管理
    如何知道单片机程序占了多少字节
    观念的水位
    心无旁骛,向死而生:WGDC2016给创企上的一堂课
    寻找地理可视化的引爆点
    测绘地理信息企业转型之惑
    为什么你找不到优秀的GISer?
  • 原文地址:https://www.cnblogs.com/erutsiom/p/9925442.html
Copyright © 2011-2022 走看看