Description
Input
Output
有M行,每个询问一行,输出结果mod 1,000,000,007的值。
Sample Input
10 3
3 5 1 2 3 1 3 5 2 1
7 9
3 9
2 3
Sample Output
10
19
6
Data Constraint
对于30%的数据,N,M<=1000
对于50%的数据,N,M<=30000
对于100%的数据,N,M<=100000
题解
老纪看了想打人系列
校长处分警告
好吧,这题还挺裸的,一道裸的莫队。
练练手,还是挺好玩的。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const long long mo=1000000007;
const int maxn=100010;
int n,m,a[maxn],x[maxn],y[maxn],p[maxn],q[maxn],id[maxn],coun;
long long ny[maxn],t[maxn],answer,js[maxn],ans[maxn],op;
long long qsm(long long a,long long b)
{
long long t=1;
long long y=a;
while (b>0)
{
if ((b&1)==1) t=t*y%mo;
y=y*y%mo;
b/=2;
}
return t;
}
void qsort(int l,int r)
{
int i=l;int j=r;
int m=p[(i+j)/2];
int m1=q[(i+j)/2];
while (i<=j)
{
while ((p[i]<m) || (p[i]==m && q[i]<m1)) i++;
while ((p[j]>m) || (p[j]==m && q[j]>m1)) j--;
if (i<=j)
{
swap(p[i],p[j]);
swap(q[i],q[j]);
swap(x[i],x[j]);
swap(y[i],y[j]);
swap(id[i],id[j]);
i++;j--;
}
}
if (l<j) qsort(l,j);
if (r>i) qsort(i,r);
}
void md(int x,int y,int p)
{
for (register int i=x;i<=y;i++)
{
coun++;
answer=(answer-js[a[i]])%mo;
t[a[i]]+=p;
if (p==-1) op=ny[a[i]];
else op=a[i];
js[a[i]]=js[a[i]]*op%mo;
if (t[a[i]]==0) js[a[i]]=0;
if (t[a[i]]==1 && p==1 && js[a[i]]==0) js[a[i]]=op;
answer=(answer+js[a[i]])%mo;
}
}
int main()
{
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
ny[0]=ny[1]=1;
for (int i=2;i<=100000;i++)
{
ny[i]=((mo-mo/i)*ny[mo%i])%mo;
}
scanf("%d%d",&n,&m);
int g=sqrt(n);
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x[i],&y[i]);
id[i]=i;
p[i]=x[i]/g+1;
q[i]=y[i]/g+1;
}
qsort(1,m);
int l=x[1];
int r=y[1];
for (int i=l;i<=r;i++)
{
t[a[i]]++;
}
answer=0;
for (int i=1;i<=100000;i++)
{
if (t[i]>0)
{
js[i]=qsm(i,t[i]);
answer=(answer+js[i])%mo;
}
}
ans[id[1]]=answer;
for (int i=2;i<=m;i++)
{
if (y[i]>r)
{
md(r+1,y[i],1);
}
else
if (y[i]<r)
{
md(y[i]+1,r,-1);
}
if (x[i]>l)
{
md(l,x[i]-1,-1);
}
else
if (x[i]<l)
{
md(x[i],l-1,1);
}
ans[id[i]]=answer;
l=x[i];r=y[i];
// printf("%d\n",coun);
}
for (int i=1;i<=m;i++)
printf("%lld\n",(ans[i]+mo)%mo);
}