请求开大时限
查看原帖
请求开大时限
58367
lnzwz楼主2022/6/9 20:58

本人的O(n1.5)O(n^{1.5})分块,死活过不去。

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define B 320
#define BK 320
#define S 100000
namespace IO {
	inline char nc(){
		static char buf[100000],*p1=buf,*p2=buf;
		return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
	}
	template<typename T> inline T read(){
		char ch=nc(); T sum=0; bool f=false;
		for(;ch<'0'||ch>'9';ch=nc()) if(ch=='-') f=1;
		while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
		return f ? -sum : sum;
	}
}
#define read IO::read<int>
int bl[320],br[320],ku[100010],sz[100010],K;
void fenk(int n)
{
    while(1)
    {
        K+=1;bl[K]=br[K-1]+1;
        br[K]=bl[K]+BK-1;
        if(br[K]>=n)
            {br[K]=n;break;}
    }
    for(int i=1;i<=K;i++)
        for(int j=bl[i];j<=br[i];j++)ku[j]=i;
}
struct lin
{
    int s1[100010],s2[320],pp[321],cz,kl,kr;short qq[100010];
    void lisan()
    {
        for(int i=kl,j=0;i<=kr;i++)
        {
            int z=sz[i];
            if(qq[z]==0)qq[z]=++j;
            pp[sz[i]=qq[z]]=z;
        }
    }
    void baoli(int l,int r,int x,int y)
    {
        for(int i=kl;i<=kr;i++)
        {
            sz[i]=pp[sz[i]];
            qq[sz[i]]=0;
        }
        for(int i=l;i<=r;i++)
            if(sz[i]==x)sz[i]=y,cz+=1;
        lisan();
    }
    void solve(int x,int y,int lx,int ly)
    {
        int sx=s1[x]-lx,sy=s1[y]-ly;
        if(sx==0)return;
        if(sy==0)
        {
            pp[qq[x]]=y;cz=sx;
            qq[y]=qq[x];qq[x]=0;
            return;
        }
        baoli(kl,kr,x,y);
    }
}zz[320];
void modify(int l,int r,int x,int y)
{
    if(x==y)return;
    int a=ku[l],b=ku[r],kx=x/B,ky=y/B;
    for(int i=1;i<=K;i++)zz[i].cz=0;
    if(a<b)
    {
        zz[a].baoli(l,br[a],x,y);
        for(int i=a+1;i<b;i++)
            zz[i].solve(x,y,zz[i-1].s1[x],zz[i-1].s1[y]);
        zz[b].baoli(bl[b],r,x,y);
    }
    else zz[a].baoli(l,r,x,y);
    for(int i=a;i<=K;i++)
    {
        int t=(zz[i].cz+=zz[i-1].cz);
        zz[i].s1[x]-=t;zz[i].s1[y]+=t;
    }
    if(kx!=ky)
    {
        for(int i=a;i<=K;i++)
        {
            zz[i].s2[kx]-=zz[i].cz;
            zz[i].s2[ky]+=zz[i].cz;
        }
    }
}
int ff[100010],gg[320],st[100010],tp;
void lingsan(int l,int r,int k)
{
    for(int j=l;j<=r;j++)
    {
        int z=zz[k].pp[sz[j]];
        st[tp++]=z;ff[z]+=1;gg[z/B]+=1;
    }
}
int main()
{
    int n,m;
    n=read();m=read();
    fenk(n);
    for(int i=1;i<=n;i++)
    {
        sz[i]=read();int k=ku[i],a=sz[i];
        zz[k].s1[a]+=1;zz[k].s2[a/B]+=1;
    }
    for(int x=1;x<=K;x++)
    {
        for(int i=1;i<=100000;i++)
            zz[x].s1[i]+=zz[x-1].s1[i];
        for(int i=0;i<=312;i++)
            zz[x].s2[i]+=zz[x-1].s2[i];
        zz[x].kl=bl[x];zz[x].kr=br[x];
        zz[x].lisan();
    }
    for(int i=0;i<m;i++)
    {
        int lx,l,r,x;
        lx=read();l=read();r=read();x=read();
        if(lx==1)
        {
            int y=read();
            modify(l,r,x,y);
        }
        else
        {
            int a=ku[l],b=ku[r],w=0;tp=0;
            if(a==b)
                lingsan(l,r,a),a-=1;
            else
                lingsan(l,br[a],a),lingsan(bl[b],r,b);
            while(1)
            {
                int s=zz[b-1].s2[w]-zz[a].s2[w]+gg[w];
                if(x<=s)break;x-=s;w+=1;
            }
            w*=B;
            while(x>0)
            {
                x-=zz[b-1].s1[w]-zz[a].s1[w]+ff[w];
                w+=1;
            }
            for(int j=0;j<tp;j++)
                ff[st[j]]=gg[st[j]/B]=0;
            printf("%d\n",w-1);
        }
    }
    return 0;
}
2022/6/9 20:58
加载中...