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;
}
不知道是思路问题还是代码有细节不到位感觉题解讲的也模糊