救救凉透了的蒟蒻吧
查看原帖
救救凉透了的蒟蒻吧
920358
kmguochang楼主2024/11/20 22:31

https://www.luogu.com.cn/record/190070967

https://www.luogu.com.cn/record/190071109

https://www.luogu.com.cn/record/190071367

如大家所见,调了一晚上以破防的我最后将N从5e5开到3e6仅仅是将8个RE变为8个WA代码如下

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3e6+6666;
int n,t,a[N],nxt[N],b[N],btp,id_x[N],head[N],cnt,f[N][36],lg[N],idx[N][36],stck[N],top;
ll dis[N];
struct Edge{
    int nxt,to;
    ll data;
}e[N<<1];
void add_edge(int from,int to,ll data){
    e[++cnt]=Edge{head[from],to,data},head[from]=cnt;
    e[++cnt]=Edge{head[to],from,data},head[to]=cnt;
    return;
}
void dfs(int u,int fa){
    int v;
    for(int i=head[u];i;i=e[i].nxt){
        v=e[i].to;
        if(v==fa)
            continue;
        dis[v]=dis[u]+e[i].data;
        dfs(v,u);
    }
    return;
}
void init(){
    lg[1]=0;
    for(int i=2;i<N;++i)
        lg[i]=lg[i>>1]+1;
    for(int i=1;i<=n;++i)
        f[i][0]=a[i],idx[i][0]=i;
    for(int i=1;i<=lg[n];++i)
        for(int j=1;j+(1<<i)<=n+1;++j){
            f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);
            idx[j][i]= f[j][i]==f[j][i-1]? idx[j][i-1]:idx[j+(1<<(i-1))][i-1];
        }
    return;
}
ll query(int x,int y){
    int lgk=lg[y],k;
    ll ans=0ll;
    k=max(f[x][lgk],f[x+y-(1<<lgk)][lgk]);
    //printf("%d %d  ",y,k);
    k= k==f[x][lgk]? idx[x][lgk]:idx[x+y-(1<<lgk)][lgk];
    //printf("%d %d %d %d ",x,lgk,y,k);
    ans+=dis[x]-dis[k];
    ans+=1ll*a[k]*(x+y-k);
    return ans;
}
int main(){
    int x,y;
    ll u,v,lst=0ll;
    scanf("%d%d",&n,&t);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        b[++btp]=a[i];
    }
    sort(b+1,b+btp+1);
    stck[0]=n+1;
    btp=unique(b+1,b+btp+1)-b-1;
    for(int i=n;i;--i){
        id_x[i]=lower_bound(b+1,b+btp+1,a[i])-b;
        while(top&&id_x[stck[top]]<=id_x[i])
            top--;
        nxt[i]= stck[top];//单调栈预处理
        stck[++top]=i;
        add_edge(i,nxt[i],1ll*a[i]*(nxt[i]-i));//建树
    }
    dfs(n+1,0);
    init();//RMQ预处理
    cout<<log2(N-1)<<" "<<lg[N-1];
    /*for(int i=1;i<=n;++i)
        printf("%d ",nxt[i]);
    printf("\n");*/
    /*for(int i=1;i<=n;++i)
        printf("%d %lld\n",nxt[i],dis[i]);
    printf("\n");*/
    for(int i=1;i<=t;++i){
        scanf("%lld%lld",&u,&v);
        x=(int)(u^lst)%n+1;
        y=(int)(v^(lst+1))%(n-x+1)+1;
        lst=query(x,y);//树上的计算
        printf("%lld\n",lst);
    }
    return 0;
}

不知道是思路问题还是代码有细节不到位感觉题解讲的也模糊

2024/11/20 22:31
加载中...