完整代碼html
#include <bits/stdc++.h> #define N 100005 #define ll long long #define getchar nc using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int read() { register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f; } inline void write(register int x) { if(!x)putchar('0');if(x<0)x=-x,putchar('-'); static int sta[20];register int tot=0; while(x)sta[tot++]=x%10,x/=10; while(tot)putchar(sta[--tot]+48); } struct query{ int l,r,p,id,bl; }q[N]; int n,m,blocksize,a[N],ans[N]; inline bool cmp(register query a,register query b) { return a.bl!=b.bl?a.l<b.l:((a.bl&1)?a.r<b.r:a.r>b.r); } int pre[N],nxt[N],head=0,vis[N],cnt[N]; ll sum[N]; inline void add(register int x) { nxt[x]=head,pre[head]=x; head=x,pre[x]=0; } inline void del(register int x) { if(x==head) head=nxt[x]; else nxt[pre[x]]=nxt[x],pre[nxt[x]]=pre[x]; } inline void change(register int x,register int type) { if(cnt[a[x]]) { sum[cnt[a[x]]]-=a[x]; if(--vis[cnt[a[x]]]==0) del(cnt[a[x]]); } cnt[a[x]]+=type; if(cnt[a[x]]) { sum[cnt[a[x]]]+=a[x]; if(++vis[cnt[a[x]]]==1) add(cnt[a[x]]); } } int p,f[1000],g[1000]; inline int add(register int x,register int y) { x+=y; if(x>=p) x-=p; return x; } inline int mul(register int x,register int y) { return 1ll*x*y-1ll*x*y/p*p; } inline void init(register int n) { f[0]=g[0]=1; for(register int i=1;i<=blocksize;++i) f[i]=add(f[i-1],f[i-1]); for(register int i=1;i<=n/blocksize;++i) g[i]=mul(g[i-1],f[blocksize]); } inline int Pow(register int n) { return mul(g[n/blocksize],f[n%blocksize]); } inline int query(register int l,register int r,register int mod) { p=mod; init(r-l+1); int ans=0; for(register int i=head;i;i=nxt[i]) ans=add(ans,mul(sum[i]%p,add(Pow(r-l+1),p-Pow(r-l+1-i)))); return ans; } int main() { n=read(),m=read(); blocksize=(int)sqrt(n); for(register int i=1;i<=n;++i) a[i]=read(); for(register int i=1;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].p=read(),q[i].id=i,q[i].bl=(q[i].l-1)/blocksize+1; sort(q+1,q+1+m,cmp); int l=1,r=0; for(register int i=1;i<=m;++i) { while(l>q[i].l) change(--l,1); while(r<q[i].r) change(++r,1); while(l<q[i].l) change(l++,-1); while(r>q[i].r) change(r--,-1); ans[q[i].id]=query(q[i].l,q[i].r,q[i].p); } for(register int i=1;i<=m;++i) write(ans[i]),puts(""); return 0; }