555我好弱啊
都说今年的HNOI是无脑数据结构赛,都很好想只是码代码的问题,然而我还是不会做这道题。
要退役了啊啊啊。
首先我们令
对于
当
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<map> using namespace std; const int N=100005; int n,m,cnt,block; long long p,ans; char str[N]; int belong[N],id[N],num[N]; long long s1[N],s2[N]; long long s[N],Ans[N]; map<long long,int> mp; struct query { int l,r,id; }q[N]; inline long long read() { long long a=0,f=1; char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();} while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();} return a*f; } inline bool operator<(query a,query b) { return belong[a.l]==belong[b.l]?a.r<b.r:a.l<b.l; } long long get(long long x) { return x*(x-1)>>1ll; } inline void solve() { for (int i=1;i<=n;i++) if (str[i]%p==0) s1[i]=s1[i-1]+1,s2[i]=s2[i-1]+i; else s1[i]=s1[i-1],s2[i]=s2[i-1]; m=read(); for (int i=1;i<=m;i++) { int l=read(),r=read(); printf("%lld\n",s2[r]-s2[l-1]-(s1[r]-s1[l-1])*(l-1)); } } int main() { p=read(); scanf("%s",str+1); n=strlen(str+1); for (int i=1;i<=n;i++) str[i]-='0'; if (p==2||p==5) {solve(); return 0;} block=(int)sqrt(n); for (int i=1;i<=n;i++) belong[i]=(i-1)/block+1; long long base=1; for (int i=n;i;i--) { base=base*10%p; s[i]=(s[i+1]+str[i]*base%p)%p; if (!mp[s[i]]) mp[s[i]]=++cnt; } for (int i=1;i<=n+1;i++) id[i]=mp[s[i]]; m=read(); for (int i=1;i<=m;i++) q[i].l=read(),q[i].r=read()+1,q[i].id=i; sort(q+1,q+m+1); int l=1,r=0; for (int i=1;i<=m;i++) { for (;r>q[i].r;r--) ans-=get(num[id[r]]),num[id[r]]--,ans+=get(num[id[r]]); for (;r<q[i].r;r++) ans-=get(num[id[r+1]]),num[id[r+1]]++,ans+=get(num[id[r+1]]); for (;l<q[i].l;l++) ans-=get(num[id[l]]),num[id[l]]--,ans+=get(num[id[l]]); for (;l>q[i].l;l--) ans-=get(num[id[l-1]]),num[id[l-1]]++,ans+=get(num[id[l-1]]); Ans[q[i].id]=ans; } for (int i=1;i<=m;i++) printf("%lld\n",Ans[i]); return 0; }