bzoj 2724: [Violet 6] dandelion

Block

It provides several precautions need to know.

First time complexity of the number of violent statistical range close to the public \ (O (the n-^ 2) \) , time complexity is not good enough, so weFailing to decision blockConsider segmentation process. Data range is relatively large, so we are discrete. After the so-called discrete data is sorted by rank instead of ta ta itself (need to open another array). \ (nlog (n) \) time to complete.

void yych()//离散化 
{
    len=sqrt(n);
    memset(L,0x3f,sizeof(L));
    for(int i=1;i<=n;++i)
    {
        pos[i]=(i-1)/len+1;
        L[pos[i]]=min(L[pos[i]],i);
        R[pos[i]]=max(R[pos[i]],i);
        a[i]=read();
        b[i]=a[i];  
    }
    sort(b+1,b+1+n);
    tot=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
}

Then we consider block preprocessing. We can first deal with a number of occurrences of each digit prefix and in the block. Each number is the enumeration \ (O (n-) \) , each block enumeration time \ (O (\ sqrt n-) \) , so the total time is \ (O (n-\ sqrt n-) \) . Then we can deal with from the first \ (L \) th block to \ (R & lt \) with intervals all the blocks. We enumerate \ (L \) complexity is \ (O (\ sqrt n-) \) , enumeration \ (R & lt \) complexity is \ (O (\ sqrt n-) \) , then the enumerator block time complexity of each number is \ (O (\ sqrt n-) \) , that is, a total of \ (O (n-\ sqrt n-) \) .

void Treaker()//分块预处理 
{
    for(int i=1;i<=n;++i)
    for(int j=pos[i];j<=pos[n];++j)s[j][a[i]]++;
    
    for(int i=1;i<=pos[n];++i)
    {
        memset(tong,0,sizeof(tong));
        for(int j=i;j<=pos[n];++j)
        {
            p[i][j]=p[i][j-1];
            for(int k=L[j];k<=R[j];++k)
            {
                tong[a[k]]++;
                if((tong[a[k]]>tong[p[i][j]])||(tong[a[k]]==tong[p[i][j]]&&a[k]<p[i][j]))p[i][j]=a[k];
            }
        }
    }
    memset(tong,0,sizeof(tong));
}

One very important thing is

p[i][j]=p[i][j-1];

Since we first need to inherit all the previous interval number, and then be able to compare update. Otherwise, they would listen to the sound of a WA, I just have to hang in here a lot of times the TAT.

Asks the operator is then, according to block our intuition, debris should be engaged in violence, Sao entire operation. So we have to \ (pos_r- pos_l \ le2 \) case of direct violence on OK.

if(pos[r]-pos[l]<=2)
    {
        int res=0;
        for(int i=l;i<=r;++i)
        {
            ++tong[a[i]];
            if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
        }
        for(int i=l;i<=r;++i)tong[a[i]]=0;
        return res;
    }

For other cases, we know that we are asking the answer, either in a single piece of the mode, either in the digital debris. For debris in the figures that we have previously processed a piece of prefix numbers appear and so we can count the number of occurrences of debris in the range of numbers in the inquiry. For the entire number in the public, we are also able to \ (O (\ sqrt n) \) within the complexity of the statistics ta number of occurrences in the debris of. So we can get in the mode interval we asked.

int res=0;
    for(int i=l;i<=R[pos[l]];++i)if(!tong[a[i]])tong[a[i]]+=s[pos[r]-1][a[i]]-s[pos[l]][a[i]];
    for(int i=L[pos[r]];i<=r;++i)if(!tong[a[i]])tong[a[i]]+=s[pos[r]-1][a[i]]-s[pos[l]][a[i]];
    for(int i=l;i<=R[pos[l]];++i)
    {
        ++tong[a[i]];
        if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
    }
    for(int i=L[pos[r]];i<=r;++i)
    {
        ++tong[a[i]];
        if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
    }
    int k=p[pos[l]+1][pos[r]-1];
    int lin=s[pos[r]-1][k]-s[pos[l]][k];
    for(int i=l;i<=R[pos[l]];++i)lin+=(a[i]==k);
    for(int i=L[pos[r]];i<=r;++i)lin+=(a[i]==k);
    if(lin>tong[res]||(lin==tong[res]&&k<res))res=k;
    
    for(int i=l;i<=R[pos[l]];++i)tong[a[i]]=0;
    for(int i=L[pos[r]];i<=r;++i)tong[a[i]]=0;
    return res;

Another point is the number of times we appear in the statistics for each digit we need to open a bucket array, every time we do not run out after all the empty, only the empty we used to look to Ke friends. Measured can save a lot of time.

Finally, talk about precautions:

1. Note that discrete, or directly to the RE-situ take-off.

2. Note that the transfer p array, WA to suspect otherwise life.

3. Note the boundary of the block, or TLE place to direct the explosion.

Also I heard that open \ (n ^ {\ frac { 1} {3}} \) blocks will be faster, the great God who will give Wo explain it? QAQ

The last offer nest ugly code:

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,tot,len,l,r,ans;
const int N=40010,M=50010,K=510;
int a[N],b[N],pos[N],s[K][N],L[K],R[K],p[K][K],tong[N];
int read()
{
    char ch;int x=0,f=1;
    while(!isdigit(ch=getchar()))
    {(ch=='-')&&(f=-f);}
    while(isdigit(ch))
    {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int cnt=0;
void yych()//离散化 
{
    len=sqrt(n);
    memset(L,0x3f,sizeof(L));
    for(int i=1;i<=n;++i)
    {
        pos[i]=(i-1)/len+1;
        L[pos[i]]=min(L[pos[i]],i);
        R[pos[i]]=max(R[pos[i]],i);
        a[i]=read();
        b[i]=a[i];  
    }
    sort(b+1,b+1+n);
    tot=unique(b+1,b+1+n)-b-1;
    for(int i=1;i<=n;++i)a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
}
void Treaker()//分块预处理 
{
    for(int i=1;i<=n;++i)
    for(int j=pos[i];j<=pos[n];++j)s[j][a[i]]++;
    
    for(int i=1;i<=pos[n];++i)
    {
        memset(tong,0,sizeof(tong));
        for(int j=i;j<=pos[n];++j)
        {
            p[i][j]=p[i][j-1];
            for(int k=L[j];k<=R[j];++k)
            {
                tong[a[k]]++;
                if((tong[a[k]]>tong[p[i][j]])||(tong[a[k]]==tong[p[i][j]]&&a[k]<p[i][j]))p[i][j]=a[k];
            }
        }
    }
    memset(tong,0,sizeof(tong));
}
int ask(int l,int r)
{
    if(pos[r]-pos[l]<=2)
    {
        int res=0;
        for(int i=l;i<=r;++i)
        {
            ++tong[a[i]];
            if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
        }
        for(int i=l;i<=r;++i)tong[a[i]]=0;
        return res;
    }
    int res=0;
    for(int i=l;i<=R[pos[l]];++i)if(!tong[a[i]])tong[a[i]]+=s[pos[r]-1][a[i]]-s[pos[l]][a[i]];
    for(int i=L[pos[r]];i<=r;++i)if(!tong[a[i]])tong[a[i]]+=s[pos[r]-1][a[i]]-s[pos[l]][a[i]];
    for(int i=l;i<=R[pos[l]];++i)
    {
        ++tong[a[i]];
        if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
    }
    for(int i=L[pos[r]];i<=r;++i)
    {
        ++tong[a[i]];
        if(tong[a[i]]>tong[res]||(tong[a[i]]==tong[res]&&a[i]<res))res=a[i];
    }
    int k=p[pos[l]+1][pos[r]-1];
    int lin=s[pos[r]-1][k]-s[pos[l]][k];
    for(int i=l;i<=R[pos[l]];++i)lin+=(a[i]==k);
    for(int i=L[pos[r]];i<=r;++i)lin+=(a[i]==k);
    if(lin>tong[res]||(lin==tong[res]&&k<res))res=k;
    
    for(int i=l;i<=R[pos[l]];++i)tong[a[i]]=0;
    for(int i=L[pos[r]];i<=r;++i)tong[a[i]]=0;
    return res;
}
int main()
{
    cin>>n>>m;
    yych();
    Treaker();
    for(int i=1;i<=m;++i)
    {
        l=read();r=read();
        l=(l+ans-1)%n+1;r=(r+ans-1)%n+1;
        if(l>r)swap(l,r);
        ans=b[ask(l,r)];
        printf("%d\n",ans);
    }
    return 0;
}
/*
6 3 
1 2 3 2 1 2 
1 5 
3 6 
1 5
*/

Guess you like

Origin www.cnblogs.com/wljss/p/11566804.html