学自:http://www.cnblogs.com/Lyush/archive/2013/08/16/3263247.html
CF 86D powerful array
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
struct node
{
ll l, r, b, id;
}p[200010];
ll ans[200020];
ll q[200020];
ll h[1000020];
bool cmp(node a, node b)
{
if (a.b == b.b) return a.r < b.r;
return a.l < b.l;
}
//上下两种排序方式应该都可以
bool comp(node a, node b)
{
if (a.b == b.b) return a.r < b.r;
return a.b < b.b;
}
int main()
{
int n, m;
cin >> n >> m;
int i, j, k;
for (i = 1; i <= n; i++)
{
cin >> q[i];
}
ll sp = (ll)sqrt(1.0*n);
for (i = 1; i <= m; i++)
{
cin >> p[i].l >> p[i].r;
p[i].id = i;
p[i].b = p[i].l / sp;
}
sort(p + 1, p + 1 + m, comp);
ll l = p[1].l, r = p[1].r;
ll sum = 0;
mem(h, 0);
for (i = l; i <= r; i++)
{
ll t = q[i];
sum += 2LL * h[t] * t + t;
h[t]++;
}
ans[p[1].id] = sum;
for (i = 2; i <= m; i++)
{
int L = p[i].l, R = p[i].r;
while (r < R)
{
r++;
ll t = q[r];
sum += 2LL * h[t] * t + t;
h[t]++;
}
while (l > L)
{
l--;
ll t = q[l];
sum+=2LL * h[t] * t + t;
h[t]++;
}
while (r>R)
{
ll t = q[r];
sum += -2LL * h[t] * t + t;
r--;
h[t]--;
}
while (l < L)
{
ll t = q[l];
sum += -2LL * h[t] * t + t;
l++;
h[t]--;
}
ans[p[i].id] = sum;
}
for (i = 1; i <= m; i++)
printf("%I64d\n",ans[i]);
//system("pause");
}
BC#22 1004 NPY and girls
代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
const ll mod = 1e9 + 7;
struct node
{
ll l, r, b, id;
}p[30010];
ll ans[30020];
ll q[30020];
ll h[30020];
ll in[30010];
ll inv(ll n, ll m)
{
ll b = 1;
while (m)
{
if (m & 1) b = b*n%mod;
n = n*n%mod;
m >>= 1;
}
return b;
}
bool cmp(node a, node b)
{
if (a.b == b.b) return a.r < b.r;
return a.l < b.l;
}
//上下两种排序方式应该都可以,貌似下面的更快些~
bool comp(node a, node b)
{
if (a.b == b.b) return a.r < b.r;
return a.b < b.b;
}
int main()
{
int t, n, m;
int i, j, k;
scanf("%d",&t);
for (i = 1; i <= 30000; i++)
in[i] = inv(i, mod - 2);
while (t--)
{
scanf("%d%d",&n,&m);
for (i = 1; i <= n; i++)
{
scanf("%I64d",&q[i]);
}
ll sp = (ll)sqrt(1.0*n);
for (i = 1; i <= m; i++)
{
scanf("%I64d%I64d", &p[i].l, &p[i].r);
p[i].id = i;
p[i].b = p[i].l / sp;
}
sort(p+1,p+1+m,comp);
int l = p[1].l, r = p[1].r;
ll sz = 0;
ll sum = 1;
mem(h, 0);
for (i = l; i <= r; i++)
{
sz++;
ll te = q[i];
h[te]++;
sum = sum*sz%mod*in[h[te]] % mod;
}
ans[p[1].id] = sum;
for (i = 2; i <= m; i++)
{
ll L = p[i].l, R = p[i].r;
while (r < R)
{
sz++;
r++;
ll te = q[r];
h[te]++;
sum = sum*sz%mod*in[h[te]] % mod;
}
while (l>L)
{
sz++;
l--;
ll te = q[l];
h[te]++;
sum = sum*sz%mod*in[h[te]] % mod;
}
while (r > R)
{
ll te = q[r];
sum = sum*h[te] % mod*in[sz] % mod;
sz--;
h[te]--;
r--;
}
while (l < L)
{
ll te = q[l];
sum = sum*h[te] % mod*in[sz] % mod;
sz--;
h[te]--;
l++;
}
ans[p[i].id] = sum;
}
for (i = 1; i <= m; i++)
printf("%I64d\n",ans[i]);
}
}