• 模拟测试10 T2:模板


    大方面:

    启发式合并。

    轻的合并到重的里。

    处理轻儿子,清空。继承重儿子。

    基于时间线段树:信息处理。

    信息存储:开数组。:vector.

    开数组而不必线段树合并:线段树合并无法处理种类计数,重复。因此不能合并。因此不必每个点开线段树。

    如果要合并是为了继承之前的信息。但无法直接继承。而且打标记能够O(1)清空。所以不必浪费空间。

    为处理要处理的信息要把决策点一个一个放到线段树里处理。因此要存储。用数组,vector。

    线段树清空:打标记。标记的使用。

    处理重复的信息不好直接在线段树内部操作:考虑两个方向:1、打标记 。但几乎没有标记能解决。

    2、辅助数组直接记出现的最早的时间。一个个向里放。

    如何想到一个个向里放:启发式合并就是继承重的,轻的一个个向里放。

    Ps:昨天没理解请启发式合并。但lnc告诉他后明白了。应该去问他问明白启发式合并的流程。

      启发式合并一个个统计(向里放)是nlog的。

    我的帅比代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define F(i,a,b) for(rg int i=a;i<=b;++i)
    #define il inline 
    #define LL long long
    #define phn printf("
    ")
    #define pf(a) printf("%d ",a)
    #define rg register
    #define cri const register int
    using namespace std;
    int read();
    #define NX 100010
    int n,m,Q,ban[NX];
    int to[NX<<1],fir[NX<<1],head[NX],cnt;
    il void add(const int x,const int y){
        to[++cnt]=y;fir[cnt]=head[x];head[x]=cnt;
    }
    int adx[NX],b[NX],c[NX],id[NX];
    vector<pair<int,int> >q[NX];
    #define mp(a,b) make_pair(a,b)
    int son[NX],sz[NX];
    #define qxs(i,x) for(int i=head[x];i;i=fir[i])
    #define V to[i]
    void sear(int x,int fa){
        sz[x]=q[x].size();
        qxs(i,x){
            if(V!=fa){
                sear(V,x);
                sz[x]+=sz[V];
                if(!son[x]||sz[V]>sz[son[x]])son[x]=V;
            }
        }
    }    
    int tong[NX],ans[NX];
    struct node{
        int sum,w,cl,l,r;
    }s[NX<<2];
    #define lc s[x<<1]
    #define rc s[x<<1|1]
    #define sx s[x]
    #define MIT int z=(s[x].l+s[x].r)>>1
    void biuld(int x,int l,int r){
        s[x].l=l;s[x].r=r;sx.w=sx.sum=sx.cl=0;
        if(l==r)return ;
        MIT;biuld(x<<1,l,z);biuld(x<<1|1,z+1,r);
    }
    il void down(int x){
        lc.sum=lc.w=rc.sum=rc.w=0;
        lc.cl=rc.cl=1;
        sx.cl=0;
    }
    void chg(int x,int k,int d){
        if(sx.l==sx.r){
            sx.w=d;sx.sum=1;return ;
        }
        if(sx.cl)down(x);MIT;
        if(k<=z)chg(x<<1,k,d);
        else chg(x<<1|1,k,d);
        sx.w=lc.w+rc.w;
        sx.sum=lc.sum+rc.sum;
    }
    int ask(int x,int k){
        if(sx.sum<=k){//<=???
            return sx.w;
        }
        if(sx.cl)down(x);
        if(lc.sum>=k)return ask(x<<1,k);
        else {
            return ask(x<<1,lc.sum)+ask(x<<1|1,k-lc.sum);
        }
    }
    void dfs(int x,int fa){
        qxs(i,x){
            if(V!=fa&&V!=son[x]){
                dfs(V,x);
                int end=q[id[V]].size()-1;
                F(j,0,end){
                    tong[q[id[V]][j].first]=0;
                //    q[x].push_back(q[V][j]);
                }
                s[1].cl=1;s[1].sum=s[1].w=0;
                //q[V].clear();
            }
        }
        if(son[x])dfs(son[x],x);
        int end=q[id[x]].size()-1;
        F(i,0,end){
            cri col=q[id[x]][i].first,t=q[id[x]][i].second;
            if(son[x])q[id[son[x]]].push_back(q[id[x]][i]);
            if(!tong[col]){
                tong[col]=t;
                chg(1,t,1);
            }
            else{
                if(tong[col]>t){
                    chg(1,tong[col],0);
                    tong[col]=t;
                    chg(1,t,1);
                }
                else {
                    chg(1,t,0);
                }
            }
        }
        if(son[x])swap(id[x],id[son[x]]);
        qxs(i,x){
            if(V!=fa&&V!=son[x]){
                end=q[id[V]].size()-1;
                F(j,0,end){
                    int col=q[id[V]][j].first,t=q[id[V]][j].second;
                    q[id[x]].push_back(q[id[V]][j]);
                    if(!tong[col]){
                        tong[col]=t;
                        chg(1,t,1);
                    }
                    else{
                        if(tong[col]>t){
                            chg(1,tong[col],0);
                            tong[col]=t;
                            chg(1,t,1);
                        }
                        else {
                            chg(1,t,0);
                        }
                    }
                }
            }
        }
        ans[x]=ask(1,ban[x]);//pf(end);phn;
    }
    int main(){
        n=read();rg int x,y;
        F(i,2,n){
            x=read();y=read();add(x,y);add(y,x);
        }
        F(i,1,n)ban[i]=read();
        m=read();
        F(i,1,m){
            adx[i]=read();b[i]=c[i]=read();
        }
        sort(c+1,c+m+1);
        int g=unique(c+1,c+m+1)-c-1;
        F(i,1,m)b[i]=lower_bound(c+1,c+g+1,b[i])-c;
        F(i,1,m){
            q[adx[i]].push_back(mp(b[i],i));
        }
        F(i,1,n)id[i]=i;
        sear(1,0);
        biuld(1,1,NX);
        dfs(1,0);
        Q=read();
        F(i,1,Q){
            x=read();
            printf("%d
    ",ans[x]);
        }
    }
    il int read(){
        int s=0,f=0;char ch;
        while(ch=getchar(),ch=='-'?f=1:0,ch<'0'||ch>'9');
        while(ch>='0'&&ch<='9'){
            s=s*10+(ch^48);ch=getchar();
        }
        return f?-s:s;
    }
    /*
    g++ 1.cpp -g
    ./a.out
    10
    3 10
    2 5
    3 2
    2 6
    1 9
    8 7
    7 4
    3 8
    3 1
    15 47 23 22 9 16 45 39 21 13
    10
    10 7
    9 3
    5 1
    5 2
    9 4
    10 9
    2 4
    10 1
    2 6
    7 9
    3
    1
    2
    3
    
    
    */
    View Code

    我们的红太阳,日本搭次客的秋田犬,exface脸的lowbi指针打法:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<map>
    using namespace std;
    const int N=100010;
    map<int,int> mp;
    vector<pair<int,int> > ve[N];//time color
    int n,m,q,ct;
    int tot,head[N],nxt[N*2],to[N*2];
    int k[N],ans[N],size[N],son[N],fir[N];
    struct segtree{
        struct node{
            node *lch,*rch;
            int sum,cnt;
            void update(){
                sum=(lch?lch->sum:0)+(rch?rch->sum:0);
                cnt=(lch?lch->cnt:0)+(rch?rch->cnt:0);
            }
        }pool[N*100],*root;
        int cnt;
        node *New(){
            pool[++cnt].lch=pool[cnt].rch=0;
            pool[cnt].cnt=pool[cnt].sum=0;
            return &pool[cnt];
        }
        void valadd(node *&p,int l,int r,int pos,int add)
        {
            if(!p) p=New();
            if(l==r) return (void)(p->sum+=add);
            int mid=l+r>>1;
            if(pos<=mid) valadd(p->lch,l,mid,pos,add);
            else valadd(p->rch,mid+1,r,pos,add);
            p->update();
        }
        void cntadd(node *&p,int l,int r,int pos)
        {
            if(!p) p=New();
            if(l==r) return (void)(++p->cnt);
            int mid=l+r>>1;
            if(pos<=mid) cntadd(p->lch,l,mid,pos);
            else cntadd(p->rch,mid+1,r,pos);
            p->update();
        }
        int query(node *p,int k,int l,int r){
            if(!p) return 0;
            if(k>=p->cnt) return p->sum;
            int mid=l+r>>1;
            if((p->lch?p->lch->cnt:0)>=k) return query(p->lch,k,l,mid);
            return query(p->rch,k-(p->lch?p->lch->cnt:0),mid+1,r)+(p->lch?p->lch->sum:0);
        }
        void clear(){
            cnt=0; root=0;
        }
    }st;
    inline void add(int a,int b){
        to[++tot]=b;
        nxt[tot]=head[a];
        head[a]=tot;
    }
    inline int read(){
        int x; scanf("%d",&x);
        return x;
    }
    void pre(int x,int fa){
        for(int i=head[x];i;i=nxt[i]){
            if(to[i]==fa) continue;
            pre(to[i],x);
            size[x]+=size[to[i]];
            if(size[to[i]]>=size[son[x]]) son[x]=to[i];
        }
        size[x]+=ve[x].size()+1;
    }
    void dfsupdate(int x,int fa){
        for(int i=head[x];i;i=nxt[i])
            if(to[i]!=fa) dfsupdate(to[i],x);
        for(int i=0;i<ve[x].size();++i){
            st.cntadd(st.root,1,m,ve[x][i].first);
            if(!fir[ve[x][i].second]){
                st.valadd(st.root,1,m,ve[x][i].first,1);
                fir[ve[x][i].second]=ve[x][i].first;
            }
            else if(ve[x][i].first < fir[ve[x][i].second]){
                st.valadd(st.root,1,m,ve[x][i].first,1);
                st.valadd(st.root,1,m,fir[ve[x][i].second],-1);
                fir[ve[x][i].second]=ve[x][i].first;
            }
        }
    }
    void dfsremove(int x,int fa){
        for(int i=head[x];i;i=nxt[i])
            if(to[i]!=fa) dfsremove(to[i],x);
        for(int j=0;j<ve[x].size();++j) fir[ve[x][j].second]=0;
    }
    void dfs(int x,int fa){
        for(int i=head[x];i;i=nxt[i])
            if(to[i]!=fa&&to[i]!=son[x])
            {
                dfs(to[i],x);
                st.clear(); dfsremove(to[i],x);
            }
        if(son[x]) dfs(son[x],x);
        for(int i=0;i<ve[x].size();++i)
        {
            st.cntadd(st.root,1,m,ve[x][i].first);
            if(!fir[ve[x][i].second]){
                st.valadd(st.root,1,m,ve[x][i].first,1);
                fir[ve[x][i].second]=ve[x][i].first;
            }
            else if(ve[x][i].first < fir[ve[x][i].second]){
                st.valadd(st.root,1,m,ve[x][i].first,1);
                st.valadd(st.root,1,m,fir[ve[x][i].second],-1);
                fir[ve[x][i].second]=ve[x][i].first;
            }
        }
        for(int i=head[x];i;i=nxt[i])
            if(to[i]!=fa&&to[i]!=son[x]) dfsupdate(to[i],x);
        ans[x]=st.query(st.root,k[x],1,m);
    }
    int main(){
        //freopen("x.in","r",stdin);
        //freopen("me.out","w",stdout);
        scanf("%d",&n);
        for(int i=1,a,b;i<n;++i){
            scanf("%d%d",&a,&b);
            add(a,b); add(b,a);
        }
        for(int i=1;i<=n;++i) scanf("%d",&k[i]);
        scanf("%d",&m);
        for(int i=1,a,b;i<=m;++i){
            scanf("%d%d",&a,&b);
            if(!mp[b]) mp[b]=++ct;
            ve[a].push_back(make_pair(i,mp[b]));
        }
        pre(1,0);
        dfs(1,0);
        scanf("%d",&q);
        while(q--) printf("%d
    ",ans[read()]);
        return 0;
    }
    View Code
    Informatik verbindet dich und mich. 信息将你我连结。
  • 相关阅读:
    bzoj4734
    51nod1056
    51nod1048
    51nod1248
    51nod1044
    51nod1132
    51nod1146
    51nod1226
    Spring Boot: Jdbc javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
    sqlserver命令创建数据库和表 demo
  • 原文地址:https://www.cnblogs.com/seamtn/p/11270492.html
Copyright © 2020-2023  润新知