回滚莫队WA 52pts求助
查看原帖
回滚莫队WA 52pts求助
526677
封禁用户楼主2023/7/17 21:27

rt,看了一下错的点,应该都是全输出的零,不知道为什么数据大了就这样,求大佬帮忙QWQ

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2*114514,M=1919810; //数组都开这么大了QAQ
ll n,m,w[M],cnt[M],bel[M],nq,ns,now;
ll v[M],tot,res[M];
struct query{
    ll l,r,id,flag;
}q[M];
bool cmp(query x,query y){
    return bel[x.l]^bel[y.l]?bel[x.l]<bel[y.l]:x.r<y.r;
}
ll st[M]; //记录每个数最早出现位置
ll ed[M],CT[M]; //记录每个数最晚出现位置—清空出现过的数 
ll work(ll l,ll r){
    ll last[M],ans=0;
    for(int i=l;i<=r;++i) last[w[i]]=0;
    for(int i=l;i<=r;++i) !last[w[i]]?last[w[i]]=i:ans=max(ans,i-last[w[i]]);
    return ans;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin>>n; ns=sqrt(n); nq=n/ns;
    for(int i=1;i<=n;++i) cin>>w[i],v[i]=w[i];
    sort(v+1,v+n+1);
    ll nm=unique(v+1,v+n+1)-v-1;
    for(int i=1;i<=n;++i)
        w[i]=lower_bound(v+1,v+nm+1,w[i])-v; //还是要离散
    cin>>m;
    for(int i=1;i<=m;++i) cin>>q[i].l>>q[i].r,q[i].id=i;
    for(int i=1;i<=nq;++i)
        for(int j=ns*(i-1)+1;j<=ns*i;++j)
            bel[j]=i;
    sort(q+1,q+m+1,cmp);
    //cout<<"QWQ";
    //for(int i=1;i<=m;++i) cout<<q[i].id<<'\n';
    for(int i=1,j=1;j<=nq;++j){ //枚举块
        ll right=min(n,j*ns),l=right+1,r=right,ans=0;
        //当前块右边界—左右指针—答案—枚举询问指针
        tot=0; //清空数组的指针
        for( ;bel[q[i].l]==j;++i){
            if(bel[q[i].r]==j){ //如果在同一块内 
                res[q[i].id]=work(q[i].l,q[i].r); //暴力扫一遍
                continue;
            }
            while(r<q[i].r){ //r向右跳 
                ed[w[++r]]=r; //先保存最后出现位置 
                if(!st[w[r]]) st[w[r]]=r,CT[++tot]=w[r]; //保存最早出现位置,并保存要删除的数 
                ans=max(ans,r-st[w[r]]); //答案完全在右区间中
            }
            ll temp=ans;
            while(l>q[i].l){ //l向左跳不用向右 
                --l;
                if(ed[w[l]]) ans=max(ans,ed[w[l]]-l);
                else ed[w[l]]=l; //可能在左区间中
            }
            res[q[i].id]=ans;
            while(l<=right){
                if(ed[w[l]]==l) ed[w[l]]=0; //去掉原来答案贡献
                ++l;
            }
            ans=temp; //去掉贡献 
        }
        for(int i=1;i<=tot;++i) ed[CT[i]]=st[CT[i]]=0; //清空
    }
    for(int i=1;i<=m;++i) cout<<res[i]<<'\n';
    return 0;
}
/*
8
1 6 2 2 3 3 1 6
5
1 4
2 5
2 8
5 6
1 7
*/
2023/7/17 21:27
加载中...