萌新刚学分块,1WA19RE

P4168 [Violet] 蒲公英

typedef @ 2020-08-26 20:18:23

RT,样例是能过
希望大佬帮忙看下

/*
数组没开够,爆零两行泪
longlong开成int,爆零两行泪
多组忘清空,爆零两行泪
 dp 没初值,爆零两行泪
深搜没边界,爆零两行泪
广搜忘出队,爆零两行泪
输入没加 &,爆零两行泪
模数没看见,爆零两行泪
 -1 不输出,爆零两行泪
越界不特判,爆零两行泪
线段树开一倍,爆零两行泪
无向变有向,爆零两行泪
题意没审清,爆零两行泪
文件名起错,爆零两行泪
调试忘删除,爆零两行泪
没用freopen,爆零两行泪
*/
#include<bits/stdc++.h>
using namespace std;
const int N=40006,T=37;//4w的三次方根 ,N是蒲公英的种类标记 
int a[N],b[N],L[N],R[N],pos[N],c[T][T][N],f[T][T][2],now[2];
inline void work(int x,int y,int num){
    ++c[x][y][num];//c[0][0][a[i]]记录不是整块的蒲公英数量 
    if(c[x][y][num]>now[0]||c[x][y][num]==now[0]&&num<now[1]){
        now[0]=c[x][y][num];//打擂台 找数量最大的蒲公英,若一样,找编号小的那个 
        now[1]=num;//种类 
    }
    return; 
}
int ask(int l,int r){
    int p=pos[l],q=pos[r];
    int x=0,y=0;
    if(p+1<=q-1){
        x=p+1;
        y=q-1;//定位到完整块 
    }
    memcpy(now,f[x][y],sizeof(now));//备份最多几个,以及是第几种 
    if(p==q){//同一区间 不完整 
        for(int i=l;i<=r;i++){
            work(x,y,a[i]);//单独统计a[i]出现的次数 
        }
        for(int i=l;i<=r;i++){
            --c[x][y][a[i]];//消除影响,便于下次统计 
        }
    }
    else{
        for(int i=l;i<=R[p];i++) work(x,y,a[i]);
        for(int i=L[q];i<=r;i++) work(x,y,a[i]);
        for(int i=l;i<=R[p];i++) --c[x][y][a[i]];
        for(int i=L[q];i<=r;i++) --c[x][y][a[i]]; 
    }
    return b[now[1]];//对应的原数 
}
int main(){
//  freopen("testin.txt","r",stdin);
//  freopen("testout.txt","w",stdout);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    memcpy(b,a,sizeof(b));
    sort(b+1,b+n+1);
    int tot=unique(b+1,b+n+1)-b-1;//一共多少种
    for(int i=1;i<=n;i++){
        a[i]=lower_bound(b+1,b+tot+1,a[i])-b;//从1开始 
    }
    int t=pow((double)n,(double)1/3);
    int len=t?n/t:n;//块数小于1,一块长度n;大于1,长度t 
    for(int i=1;i<=t;i++){
        L[i]=(i-1)*len+1;
        R[i]=i*len; 
    }
    if(R[t]<n){
        L[t+1]=R[t]+1;
        R[++t]=n;
    }
    for(int i=1;i<=t;i++){
        for(int j=L[i];j<=R[i];j++){
            pos[j]=i;
        }
    }
    memset(c,0,sizeof(c));
    memset(f,0,sizeof(f));
    for(int i=1;i<=t;i++){
        for(int j=i;j<=n;j++){
            for(int k=L[i];k<=R[i];k++)
                ++c[i][j][a[k]];//从第i分块到第j个分块,每种蒲公英的数量
            for(int k=1;k<=tot;k++){
                if(c[i][j][k]>=f[i][j][0]){
                    f[i][j][0]=c[i][j][k];//最多数量是多少 
                    f[i][j][i]=k;//具体哪(k)种数量最多
                }
            } 
        }
    }
    int x=0;
    while(m--){
        int l,r;
        scanf("%d%d",&l,&r);
        l=(l+x-1)%n+1;
        r=(r+x-1)%n+1;
        if(l>r) swap(l,r);
        x=ask(l,r);
        printf("%d\n",x); 
    }
    //分块预处理,统计每个块上蒲公英种类的数量 
    return 0;
}

by raincity @ 2020-08-26 20:21:19

头像可海星


by typedef @ 2020-08-26 20:24:55

google dino


|