• 数列分块入门 8 总结


    在这里插入图片描述
    这题我们只需设个check[i]表示第i块是否都为一个数,b[i]表示第i块变成的数。
    然后暴力搞就可以了。
    至于为什么,我们看看hzwer大佬(黄学长)的解释吧:(%d%a%l%a%o)
    在这里插入图片描述
    上标:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #define N 100010
    using namespace std;
    int n,st,a[N],bl[N],le[N],ri[N];
    int b[321],check[321],l,r,c;
    
    inline int read()
    {
    	int x=0,f=0; char c=getchar();
    	while (c<'0' || c>'9') f=(c=='-') ? 1:f,c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return f ? -x:x;
    }
    
    void update(int x)
    {
    	if (!check[x]) return;
    	for (int i=le[x];i<=ri[x];i++) a[i]=b[x];
    	check[x]=0,b[x]=-1;
    }
    
    int q_c(int l,int r,int c)
    {
    	int ans=0;
    	update(bl[l]);
    	for (int i=l;i<=min(ri[bl[l]],r);i++)
    		if (a[i]==c) ans++; else a[i]=c;
    	if (bl[l]!=bl[r])
    	{
    		update(bl[r]);
    		for (int i=le[bl[r]];i<=r;i++)
    			if (a[i]==c) ans++; else a[i]=c;
    	}
    	for (int i=bl[l]+1;i<=bl[r]-1;i++)
    		if (check[i])
    		{
    			if (b[i]==c) ans+=st;
    			else b[i]=c;
    		}
    		else
    		{
    			for (int j=le[i];j<=ri[i];j++)
    				if (a[j]==c) ans++;
    			check[i]=1,b[i]=c;
    		}
    	return ans;
    }
    
    int main()
    {
    	freopen("6284.in","r",stdin);
    	freopen("6284.out","w",stdout);
    	n=read(),st=sqrt(n);
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=n;i++)
    	{
    		bl[i]=(i-1)/st+1;
    		if (!le[bl[i]]) le[bl[i]]=i;
    		ri[bl[i]]=i;
    	}
    	for (int i=1;i<=n;i++)
    	{
    		l=read(),r=read(),c=read();
    		printf("%d
    ",q_c(l,r,c));
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    LL(1)文法的判断,递归下降分析程序
    消除左递归
    DFA最小化,语法分析初步
    非确定的自动机NFA确定化为DFA
    正规式、正规文法与自动机
    第03组 Alpha事后诸葛亮
    第03组 Alpha冲刺(4/4)
    第03组 Alpha冲刺(3/4)
    第03组 Alpha冲刺(2/4)
    第03组 Alpha冲刺(1/4)
  • 原文地址:https://www.cnblogs.com/jz929/p/11817610.html
Copyright © 2020-2023  润新知