简单莫队

题目:小Z的袜子

莫队:当年国家队队长莫涛大犇发明的算法orz

#include<bits/stdc++.h>

using namespace std;

const int maxn = 50010;
const int64_t mod = 1e9 + 7;

int n, m;
int k;
int x[maxn];
int sum[maxn];
struct P
{
    int l, r;
    int num;
    int64_t ans1, ans2;
}que[maxn];

bool cmp1(P x,P y)
{
    return ((x.l/k<y.l/k)||((x.l/k==y.l/k)&&(x.r<y.r)));
}
bool cmp2(P x,P y)
{
    return x.num<y.num;
}

int32_t main()
{

    //freopen("test.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    scanf("%d %d", &n, &m);
    k = sqrt(n);
    for(int i = 1; i <= n; i++)
    {
       scanf("%d", &x[i]);
    }

    for(int i = 1; i <= m; i++)
    {
        scanf("%d %d", &que[i].l, &que[i].r);
        que[i].num = i;
    }

    sort(que + 1, que + m + 1, cmp1);

    int l = 1, r = 0;
    int64_t ans = 0;
    for(int i = 1; i <= m; i++)
    {
        int L = que[i].l, R = que[i].r;
        while(L > l)
        {
            sum[x[l]]--;
            ans -= sum[x[l]];
            l++;
        }
        while(L < l)
        {
            l--;
            ans += sum[x[l]];
            sum[x[l]]++;
        }
        while(R > r)
        {
            r++;
            ans += sum[x[r]];
            sum[x[r]]++;
        }
        while(R < r)
        {
            sum[x[r]]--;
            ans -= sum[x[r]];
            r--;
        }
        que[i].ans1 = ans;
        que[i].ans2 = 1LL * (R - L + 1) * (R - L) / 2;
    }
    sort(que + 1, que + m + 1, cmp2);
    for(int i = 1; i <= m; i++)
    {
        int64_t tmp = __gcd(que[i].ans1, que[i].ans2);
        if(tmp == 0)
            cout << "0/1" << endl;
        else
            printf("%lld/%lld\n", que[i].ans1 / tmp, que[i].ans2 / tmp);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/k_ona/article/details/80851128
今日推荐