• P6466分散层叠算法(Fractional Cascading)【模板】


    正题

    题目链接:https://www.luogu.com.cn/problem/P6466


    题目大意

    给出\(k\)个长度为\(n\)的有序序列,\(q\)次询问给出\(x\),求所有序列中\(x\)的后继的异或和。

    强制在线

    \(1\leq k\leq 100,1\leq n\leq 10^4,1\leq q\leq 5\times 10^5\)


    解题思路

    一个很神奇的算法,考虑如果我们将一个序列的偶数位提取出来,我们得到在这些偶数位中\(x\)的后继的话,那么原来序列中的后继中的距离不会超过\(1\)

    所以我们可以得到一个算法,考虑原来的序列为\(a_i\),开始取出\(b_k=a_k\),然后对于\(i\)\(k-1\)\(1\)\(b_{i+1}\)的偶数位提取出来和\(a_i\)合并成一个新的有序\(b_i\)

    那么求解时我们就可以只需要查询\(b_{1}\)中的后继了。

    时间复杂度:\(O(nk+q(k+\log n))\)


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    const int K=110,N=2e4+10;
    int n,k,q,d,b[K][N],c[K][N];
    int nxt[K][N],p[K][N],l[K];
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c))x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    void print(int x)
    {if(x>9)print(x/10);putchar(x%10+48);return;}
    int main()
    {
    	n=read();k=read();q=read();d=read();
    	for(int i=1;i<=k;i++){
    		for(int j=1;j<=n;j++)
    			b[i][j]=read();
    	}
    	for(int i=1;i<=n;i++)c[k][i]=b[k][i];
    	l[k]=n;
    	for(int i=k-1;i>=1;i--){
    		int z=2;
    		for(int j=1;j<=n;j++){
    			while(z<=l[i+1]&&c[i+1][z]<=b[i][j]){
    				c[i][++l[i]]=c[i+1][z];
    				p[i][l[i]]=z;
    				nxt[i][l[i]]=b[i][j];
    				z+=2;
    			}
    			c[i][++l[i]]=b[i][j];
    		}
    		while(z<=l[i+1]){
    			c[i][++l[i]]=c[i+1][z];
    			p[i][l[i]]=z;z+=2;
    		}
    		for(int j=l[i],last=l[i+1];j>=1;j--)
    			if(p[i][j])last=p[i][j];
    			else nxt[i][j]=-last;
    	}
    	int las=0;
    	for(int z=1;z<=q;z++){
    		int x,ans=0,i=1;x=read();x^=las;
    		int pos=lower_bound(c[1]+1,c[1]+1+l[1],x)-c[1];
    		ans^=p[i][pos]?nxt[i][pos]:c[i][pos];
    		while(i<=k){
    			pos=p[i][pos]?p[i][pos]:-nxt[i][pos];
    			pos--;i++;
    			while(pos<=l[i]&&c[i][pos]<x)pos++;
    			ans^=p[i][pos]?nxt[i][pos]:c[i][pos];
    		}
    		las=ans;
    		if(z%d==0)print(ans),putchar('\n');
    	}
    	return 0;
    }
    
  • 相关阅读:
    S1 商品信息管理系统
    用例图
    mvc使用mongodb时objectId序列化与反序列化
    windows下检測文件改变
    【Android 开发实例】时间管理APP开发之数据库设计
    设计模式 之 原型
    ANT安装及配置
    Java环境变量设置
    Win7安装软件,界面上中文显示乱码的解决方案
    Some perl tips
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/16015735.html
Copyright © 2020-2023  润新知