区间
本题看到就直接上高精,结果发现答案的位数大于1000就挂了
本
题
其
实
是
一
个
前
后
缀
和
优
化
的
题
目
,
类
似
分
块
(
但
由
于
长
度
为
k
,
所
以
最
多
是
1
个
块
的
长
度
)
,
所
以
O
(
1
)
可
求
出
答
案
本题其实是一个前后缀和优化的题目,类似分块(但由于长度为k,所以最多是1个块的长度),所以O(1)可求出答案
本题其实是一个前后缀和优化的题目,类似分块(但由于长度为k,所以最多是1个块的长度),所以O(1)可求出答案
先 预 处 理 出 每 个 块 的 前 缀 和 后 缀 , 然 后 l 从 1 扫 到 n , 将 以 用 前 缀 和 后 缀 算 答 案 先预处理出每个块的前缀和后缀,然后l从1扫到n,将以用前缀和后缀算答案 先预处理出每个块的前缀和后缀,然后l从1扫到n,将以用前缀和后缀算答案
由于本题空限卡得很死,所以能直接算的不要存,如belon
#include<bits/stdc++.h>
using namespace std;
const int N=2e7+5;
int n,P,k;
int s[N],B,C,D,pre[N],suf[N],ans=0;
int belon(int i){return (i-1)/k+1;}//不要开数组记录
int main(){
scanf("%d%d%d",&n,&k,&P);
scanf("%d%d%d%d",&s[1],&B,&C,&D);
B%=D,C%=D;
for(int i=2;i<=n;i++){
s[i]=(1ll*s[i-1]*B+C)%D;
}
for(int i=1;i<=n;i++){
if(i%k==1)pre[i]=s[i];
else pre[i]=1ll*pre[i-1]*s[i]%P;
}
suf[n]=s[n];
for(int i=n-1;i>=1;i--){
if(belon(i)!=belon(i+1))suf[i]=s[i];
else suf[i]=1ll*suf[i+1]*s[i]%P;
}
for(int l=1;l+k-1<=n;l++)
{
int r=l+k-1;
if(belon(l)==belon(r)){
ans^=pre[r];
}
else {
int tp1=suf[l];
int tp2=pre[r];
int summ=(1LL*tp1*tp2)%P;
ans^=summ;
}
}
printf("%d",ans);
}