zoukankan      html  css  js  c++  java
  • [学习笔记]树上莫队

    其实树上莫队是一个欧拉序而已嘛,像普通的莫队,特判一下出现过两次的值就行了

    (st_i)(i) 进栈的时间,(ed_i)(i) 出栈的时间,(dfn_x<dfn_y) ,那么就可以分两种情况:

    1、(y)(x) 子树中,也就是 (LCA(x,y)=x),那么区间转化成 ([st_x,st_y])

    2、(y) 不在 (x) 子树中,也就是 (LCA(x,y) ot =x),那么区间转化成 ([ed_x,st_y])

    然后就是板子了

    for(int i=1;i<=m;i++){
        x=read(),y=read();
        q[i].anc=LCA(x,y);q[i].id=i;
        if(x==q[i].anc||y==q[i].anc){
            q[i].anc=0;q[i].l=st[x];q[i].r=st[y];
            if(q[i].l>q[i].r) q[i].l=st[y],q[i].r=st[x];
        }
        else {
            q[i].l=ed[x];q[i].r=st[y];
            if(q[i].l>q[i].r) q[i].l=ed[y],q[i].r=st[x];
        }
    }
    

    1、SP10707 COT2 - Count on a tree II

    其实我国庆的时候就学了,只不过我一直 (WA)...后来从倍增换成树剖,重构一遍代码就 (A)

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    int n,m,a[maxn],mp[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
    int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];
    
    struct Query{
        int l,r,anc,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
        if((a.l-1)/blo!=(b.l-1)/blo)
            return (a.l-1)/blo<(b.l-1)/blo;
        return a.r<b.r;
    }
    
    inline int read(){
        register int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return (f==1)?x:-x;
    }
    inline void add(int x,int y){
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    
    void dfs1(int x,int f){
        siz[x]=1;fa[x]=f;
        dep[x]=dep[f]+1;
        st[x]=++tim;p[tim]=x;
        int maxson=-1;
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==f) continue;
            dfs1(y,x);
            siz[x]+=siz[y];
            if(maxson<siz[y]){
                maxson=siz[y];
                son[x]=y;
            }
        }
        ed[x]=++tim;p[tim]=x;
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        if(son[x]) dfs2(son[x],topf);
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==fa[x]||y==son[x]) continue;
            dfs2(y,y);
        }
    }
    
    int LCA(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return x;
    }
    
    int update(int x){
        if(vis[x]){
            if(--cnt[a[x]]==0) now--;
        }
        else if(++cnt[a[x]]==1) now++;
        vis[x]^=1;
    }
    
    int main()
    {
        n=read(),m=read();blo=sqrt(n);
        for(int i=1;i<=n;i++) mp[i]=a[i]=read();
        sort(mp+1,mp+n+1);
        int t=unique(mp+1,mp+n+1)-mp-1;
        for(int i=1;i<=n;i++) a[i]=lower_bound(mp+1,mp+t+1,a[i])-mp;
        int x,y;
        for(int i=1;i<n;i++){
            x=read(),y=read();
            add(x,y);add(y,x);
        }
        dfs1(1,0);dfs2(1,1);
        for(int i=1;i<=m;i++){
            x=read(),y=read();
            q[i].anc=LCA(x,y);q[i].id=i;
            if(x==q[i].anc||y==q[i].anc){
                q[i].anc=0;q[i].l=st[x];q[i].r=st[y];
                if(q[i].l>q[i].r) q[i].l=st[y],q[i].r=st[x];
            }
            else {
                q[i].l=ed[x];q[i].r=st[y];
                if(q[i].l>q[i].r) q[i].l=ed[y],q[i].r=st[x];
            }
        }
        sort(q+1,q+m+1,cmp);
        int L=1,R=0;
        for(int i=1;i<=m;i++){
            while(R<q[i].r) update(p[++R]);
            while(R>q[i].r) update(p[R--]);
            while(L<q[i].l) update(p[L++]);
            while(L>q[i].l) update(p[--L]);
            if(q[i].anc) update(q[i].anc);
            ans[q[i].id]=now;
            if(q[i].anc) update(q[i].anc);
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

    2、苹果树(本地Cena自测)

    其实就是特判一下 (cnt_a)(cnt_b)

    只不过我非常傻,离散了一下颜色,就 (GG)

    (Code Below:)

    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int maxn=100000+10;
    int n,m,a[maxn],mp[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
    int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];
    
    struct Query{
    	int l,r,a,b,anc,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
    	if((a.l-1)/blo!=(b.l-1)/blo)
    		return (a.l-1)/blo<(b.l-1)/blo;
    	return a.r<b.r;
    }
    
    inline int read(){
    	register int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return (f==1)?x:-x;
    }
    inline void add(int x,int y){
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    
    void dfs1(int x,int f){
    	siz[x]=1;fa[x]=f;
    	dep[x]=dep[f]+1;
    	st[x]=++tim;p[tim]=x;
    	int maxson=-1;
    	for(int i=head[x],y;i;i=nxt[i]){
    		y=to[i];
    		if(y==f) continue;
    		dfs1(y,x);
    		siz[x]+=siz[y];
    		if(maxson<siz[y]){
    			maxson=siz[y];
    			son[x]=y;
    		}
    	}
    	ed[x]=++tim;p[tim]=x;
    }
    
    void dfs2(int x,int topf){
    	top[x]=topf;
    	if(son[x]) dfs2(son[x],topf);
    	for(int i=head[x],y;i;i=nxt[i]){
    		y=to[i];
    		if(y==fa[x]||y==son[x]) continue;
    		dfs2(y,y);
    	}
    }
    
    int LCA(int x,int y){
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]]) swap(x,y);
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y]) swap(x,y);
    	return x;
    }
    
    void update(int x){
    	if(vis[x]){
    		if(--cnt[a[x]]==0) now--;
    	}
    	else if(++cnt[a[x]]==1) now++;
    	vis[x]^=1;
    }
    
    int main()
    {
    	n=read(),m=read();blo=sqrt(2*n);
    	for(int i=1;i<=n;i++) a[i]=read();
    	int x,y;
    	for(int i=1;i<=n;i++){
    		x=read(),y=read();
    		if(x&&y) add(x,y),add(y,x);
    	}
    	dfs1(1,0);dfs2(1,1);
    	for(int i=1;i<=m;i++){
    		x=read(),y=read(),q[i].a=read(),q[i].b=read();
    		q[i].anc=LCA(x,y);q[i].id=i;
    		if(x==q[i].anc||y==q[i].anc){
    			q[i].anc=0;q[i].l=st[x];q[i].r=st[y];
    			if(q[i].l>q[i].r) q[i].l=st[y],q[i].r=st[x];
    		}
    		else {
    			q[i].l=ed[x];q[i].r=st[y];
    			if(q[i].l>q[i].r) q[i].l=ed[y],q[i].r=st[x];
    		}
    	}
    	sort(q+1,q+m+1,cmp);
    	int L=1,R=0;
    	for(int i=1;i<=m;i++){
    		while(R<q[i].r) update(p[++R]);
    		while(R>q[i].r) update(p[R--]);
    		while(L<q[i].l) update(p[L++]);
    		while(L>q[i].l) update(p[--L]);
    		if(q[i].anc) update(q[i].anc);
    		ans[q[i].id]=now;
    		if(q[i].a!=q[i].b&&cnt[q[i].a]&&cnt[q[i].b]) ans[q[i].id]--;
    		if(q[i].anc) update(q[i].anc);
    	}
    	for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
    	return 0;
    }
    

    3、Haruna’s Breakfast

    小知识:带修莫队块大小在 (n^{frac 23}) 跑的最快……不过我不会证

    本人错误点:莫队修改过来的时候应该先将修改的时间戳 (+1),再更新;莫队修改回去的时候应该先更新,再将修改的时间戳 (-1)

    (Code Below:)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=100000+10;
    int n,m,a[maxn],mp[maxn],pos[maxn],val[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now,Cnum,Qnum,an;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
    int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];
    
    struct Query{
        int l,r,anc,pre,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
        if((a.l-1)/blo!=(b.l-1)/blo)
            return (a.l-1)/blo<(b.l-1)/blo;
        if(a.r!=b.r) return a.r<b.r;
        return a.pre<b.pre;
    }
    
    inline int read(){
        register int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return (f==1)?x:-x;
    }
    inline void add(int x,int y){
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    
    void dfs1(int x,int f){
        siz[x]=1;fa[x]=f;
        dep[x]=dep[f]+1;
        st[x]=++tim;p[tim]=x;
        int maxson=-1;
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==f) continue;
            dfs1(y,x);
            siz[x]+=siz[y];
            if(maxson<siz[y]){
                maxson=siz[y];
                son[x]=y;
            }
        }
        ed[x]=++tim;p[tim]=x;
    }
    
    void dfs2(int x,int topf){
        top[x]=topf;
        if(son[x]) dfs2(son[x],topf);
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==fa[x]||y==son[x]) continue;
            dfs2(y,y);
        }
    }
    
    int LCA(int x,int y){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return x;
    }
    
    inline void update(int x){
    	if(a[x]<maxn){
    		if(vis[x]){
    	        if(--cnt[a[x]]==0) now=min(now,a[x]);
    	    }
    	    else if(++cnt[a[x]]==1) while(cnt[now]) now++;
    	}
        vis[x]^=1;
    }
    
    inline void Del(int x){if(vis[x]&&a[x]<maxn) if(--cnt[a[x]]==0) now=min(now,a[x]);}
    inline void Add(int x){if(vis[x]&&a[x]<maxn) if(++cnt[a[x]]==1) while(cnt[now]) now++;}
    
    int main()
    {
        n=read(),m=read();blo=pow(2*n,0.666666);
        for(int i=1;i<=n;i++) a[i]=read();
        int opt,x,y;
        for(int i=1;i<n;i++){
            x=read(),y=read();
            add(x,y);add(y,x);
        }
        dfs1(1,0);dfs2(1,1);
        for(int i=1;i<=m;i++){
            opt=read(),x=read(),y=read();
            if(opt==0){
            	pos[++Qnum]=x;val[Qnum]=y;
    		}
    		else {
    			q[++Cnum].anc=LCA(x,y);q[Cnum].pre=Qnum;q[Cnum].id=Cnum;
    			if(x==q[Cnum].anc||y==q[Cnum].anc){
    	            q[Cnum].anc=0;q[Cnum].l=st[x];q[Cnum].r=st[y];
    	            if(q[Cnum].l>q[Cnum].r) q[Cnum].l=st[y],q[Cnum].r=st[x];
    	        }
    	        else {
    	            q[Cnum].l=ed[x];q[Cnum].r=st[y];
    	            if(q[Cnum].l>q[Cnum].r) q[Cnum].l=ed[y],q[Cnum].r=st[x];
    	        }
    		}
        }
    	sort(q+1,q+Cnum+1,cmp);
        int L=1,R=0;
        for(int i=1;i<=Cnum;i++){
            while(R<q[i].r) update(p[++R]);
            while(R>q[i].r) update(p[R--]);
            while(L<q[i].l) update(p[L++]);
            while(L>q[i].l) update(p[--L]);
            if(q[i].anc) update(q[i].anc);
            while(an<q[i].pre){
            	an++;
            	Del(pos[an]);
            	swap(a[pos[an]],val[an]);
            	Add(pos[an]);
    		}
    		while(an>q[i].pre){
    			Del(pos[an]);
    			swap(a[pos[an]],val[an]);
    			Add(pos[an]);
    			an--;
    		}
    		ans[q[i].id]=now;
            if(q[i].anc) update(q[i].anc);
        }
        for(int i=1;i<=Cnum;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

    4、GT and trees

    综合题,求树上路径待修改区间众数,不难想到带修树上莫队

    然后就再记录一个 (f[i]) 表示区间出现 (i) 次的数的个数,(add) 没什么好说的,(del) 就暴力找,跟 (mex) 一样

    (Code Below:)

    #include <cstdio>
    #include <cctype>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=100000+10;
    int n,m,a[maxn],vis[maxn],f[maxn],cnt[maxn],pos[maxn],val[maxn];
    int Ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,Cnum,Qnum,ans,now;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
    int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];
    
    struct Query{
    	int l,r,anc,pre,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
    	if((a.l-1)/blo!=(b.l-1)/blo)
    		return (a.l-1)/blo<(b.l-1)/blo;
    	if(a.r!=b.r) return a.r<b.r;
    	return a.pre<b.pre; 
    }
    
    inline int read(){
    	register int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    	while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    	return (f==1)?x:-x;
    }
    inline void add(int x,int y){
    	to[++tot]=y;
    	nxt[tot]=head[x];
    	head[x]=tot;
    }
    
    void dfs1(int x,int f){
    	siz[x]=1;fa[x]=f;
    	dep[x]=dep[f]+1;
    	st[x]=++tim;p[tim]=x;
    	int maxson=-1;
    	for(int i=head[x],y;i;i=nxt[i]){
    		y=to[i];
    		if(y==f) continue;
    		dfs1(y,x);
    		siz[x]+=siz[y];
    		if(maxson<siz[y]){
    			maxson=siz[y];
    			son[x]=y;
    		}
    	}
    	ed[x]=++tim;p[tim]=x;
    }
    
    void dfs2(int x,int topf){
    	top[x]=topf;
    	if(son[x]) dfs2(son[x],topf);
    	for(int i=head[x],y;i;i=nxt[i]){
    		y=to[i];
    		if(y==fa[x]||y==son[x]) continue;
    		dfs2(y,y);
    	}
    }
    
    int LCA(int x,int y){
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]]) swap(x,y);
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y]) swap(x,y);
    	return x;
    }
    
    inline void update(int x){
    	if(vis[x]){
    		if(--f[cnt[a[x]]--]==0) while(!f[ans]) ans--;
    	}
    	else if(++f[++cnt[a[x]]]==1) ans=max(ans,cnt[a[x]]);
    	vis[x]^=1;
    }
    
    inline void Add(int x){if(vis[x]) if(++f[++cnt[a[x]]]==1) ans=max(ans,cnt[a[x]]);}
    inline void Del(int x){if(vis[x]) if(--f[cnt[a[x]]--]==0) while(!f[ans]) ans--;}
    
    int main()
    {
    	int T=read();
    	while(T--){
    		memset(head,0,sizeof(head));
    		memset(son,0,sizeof(son));
    		memset(vis,0,sizeof(vis));
    		memset(f,0,sizeof(f));
    		memset(cnt,0,sizeof(cnt));
    		tim=tot=Cnum=Qnum=ans=now=0;
    		n=read(),m=read();blo=pow(2*n,0.666666);
    		int opt,x,y;
    		for(int i=1;i<n;i++){
    			x=read(),y=read();
    			add(x,y);add(y,x);
    		}
    		for(int i=1;i<=n;i++) a[i]=read();
    		dfs1(1,0);dfs2(1,1);
    		for(int i=1;i<=m;i++){
    			opt=read(),x=read(),y=read();
    			if(opt==0) pos[++Qnum]=x,val[Qnum]=y;
    			else {
    				q[++Cnum].anc=LCA(x,y);q[Cnum].pre=Qnum;q[Cnum].id=Cnum;
    				if(x==q[Cnum].anc||y==q[Cnum].anc){
    					q[Cnum].anc=0;
    					if(st[x]<st[y]) q[Cnum].l=st[x],q[Cnum].r=st[y];
    					else q[Cnum].l=st[y],q[Cnum].r=st[x];
    				}
    				else {
    					if(ed[x]<st[y]) q[Cnum].l=ed[x],q[Cnum].r=st[y];
    					else q[Cnum].l=ed[y],q[Cnum].r=st[x];
    				}
    			}
    		}
    		sort(q+1,q+Cnum+1,cmp);
    		int L=1,R=0;
    		for(int i=1;i<=Cnum;i++){
    			while(R<q[i].r) update(p[++R]);
    			while(R>q[i].r) update(p[R--]);
    			while(L<q[i].l) update(p[L++]);
    			while(L>q[i].l) update(p[--L]);
    			if(q[i].anc) update(q[i].anc);
    			while(now<q[i].pre){
    				now++;
    				Del(pos[now]);
    				swap(a[pos[now]],val[now]);
    				Add(pos[now]);
    			}
    			while(now>q[i].pre){
    				Del(pos[now]);
    				swap(a[pos[now]],val[now]);
    				Add(pos[now]);
    				now--;
    			}
    			Ans[q[i].id]=ans;
    			if(q[i].anc) update(q[i].anc);
    		}
    		for(int i=1;i<=Cnum;i++) printf("%d
    ",Ans[i]);
    	}
    	return 0;
    }
    

    5、[WC2013]糖果公园

    树上带修莫队 我20分钟切掉的

    其实差不多一个板子,不过我被卡常了,我 (inline+register+O_2) 才过,最大一个点 (5136ms)

    // luogu-judger-enable-o2
    #include <bits/stdc++.h>
    #define res register int
    #define ll long long
    using namespace std;
    const int maxn=100000+10;
    int n,m,Q,c[maxn],v[maxn],w[maxn],vis[maxn],cnt[maxn],pos[maxn],val[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,Cnum,Qnum,now;
    int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;ll Ans[maxn],ans;
    int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];
    
    struct Query{
        int l,r,anc,pre,id;
    }q[maxn];
    
    bool cmp(Query a,Query b){
        if((a.l-1)/blo!=(b.l-1)/blo)
            return (a.l-1)/blo<(b.l-1)/blo;
        if(a.r<b.r) return a.r<b.r;
        return a.pre<b.pre;
    }
    
    inline int read(){
        register int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return (f==1)?x:-x;
    }
    inline void add(res x,res y){
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    
    void dfs1(res x,res f){
        siz[x]=1;fa[x]=f;
        dep[x]=dep[f]+1;
        st[x]=++tim;p[tim]=x;
        int maxson=-1;
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==f) continue;
            dfs1(y,x);
            siz[x]+=siz[y];
            if(maxson<siz[y]){
                maxson=siz[y];
                son[x]=y;
            }
        }
        ed[x]=++tim;p[tim]=x;
    }
    
    void dfs2(res x,res topf){
        top[x]=topf;
        if(son[x]) dfs2(son[x],topf);
        for(int i=head[x],y;i;i=nxt[i]){
            y=to[i];
            if(y==fa[x]||y==son[x]) continue;
            dfs2(y,y);
        }
    }
    
    inline int LCA(res x,res y){
        while(top[x]!=top[y]){
            if(dep[top[x]]<dep[top[y]]) swap(x,y);
            x=fa[top[x]];
        }
        if(dep[x]>dep[y]) swap(x,y);
        return x;
    }
    
    inline void update(res x){
        if(vis[x]){
            ans-=(ll)v[c[x]]*w[cnt[c[x]]--];
        }
        else ans+=(ll)v[c[x]]*w[++cnt[c[x]]];
        vis[x]^=1;
    }
    
    inline void Del(res x){if(vis[x]) ans-=(ll)v[c[x]]*w[cnt[c[x]]--];}
    inline void Add(res x){if(vis[x]) ans+=(ll)v[c[x]]*w[++cnt[c[x]]];}
    
    int main()
    {
        n=read(),m=read(),Q=read();blo=pow(2*n,0.666666);
        for(res i=1;i<=m;i++) v[i]=read();
        for(res i=1;i<=n;i++) w[i]=read();
        res opt,x,y;
        for(res i=1;i<n;i++){
            x=read(),y=read();
            add(x,y);add(y,x);
        }
        dfs1(1,0);dfs2(1,1);
        for(res i=1;i<=n;i++) c[i]=read();
        for(res i=1;i<=Q;i++){
            opt=read(),x=read(),y=read();
            if(opt==0) pos[++Qnum]=x,val[Qnum]=y;
            else {
                q[++Cnum].anc=LCA(x,y);q[Cnum].pre=Qnum;q[Cnum].id=Cnum;
                if(x==q[Cnum].anc||y==q[Cnum].anc){
                    q[Cnum].anc=0;
                    if(st[x]<st[y]) q[Cnum].l=st[x],q[Cnum].r=st[y];
                    else q[Cnum].l=st[y],q[Cnum].r=st[x];
                }
                else {
                    if(ed[x]<st[y]) q[Cnum].l=ed[x],q[Cnum].r=st[y];
                    else q[Cnum].l=ed[y],q[Cnum].r=st[x];
                }
            }
        }
        sort(q+1,q+Cnum+1,cmp);
        res L=1,R=0;
        for(res i=1;i<=Cnum;i++){
            while(R<q[i].r) update(p[++R]);
            while(R>q[i].r) update(p[R--]);
            while(L<q[i].l) update(p[L++]);
            while(L>q[i].l) update(p[--L]);
            if(q[i].anc) update(q[i].anc);
            while(now<q[i].pre){
                now++;
                Del(pos[now]);
                swap(c[pos[now]],val[now]);
                Add(pos[now]);
            }
            while(now>q[i].pre){
                Del(pos[now]);
                swap(c[pos[now]],val[now]);
                Add(pos[now]);
                now--;
            }
            Ans[q[i].id]=ans;
            if(q[i].anc) update(q[i].anc);
        }
        for(res i=1;i<=Cnum;i++) printf("%lld
    ",Ans[i]);
        return 0;
    }
    
  • 相关阅读:
    Java day 15
    Java day 14
    Java day 13
    Java day 12
    Java day 11
    Java day 10
    Java day 9
    Java day 8
    Java day 7
    Java day 6
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/10018392.html
Copyright © 2011-2022 走看看