前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >P1494「[国家集训队]小Z的袜子」

P1494「[国家集训队]小Z的袜子」

作者头像
hotarugali
发布2022-03-18 19:49:47
2060
发布2022-03-18 19:49:47
举报
文章被收录于专栏:hotarugaliの技术分享

1. 题目

题目链接:P1494「[国家集训队]小Z的袜子」

输入输出样例

输入 #1
代码语言:javascript
复制
6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6
输出 #1
代码语言:javascript
复制
2/5
0/1
1/1
4/15

说明/提示

2. 题解

分析

一看题目,可以离线查询,而且 O(mn)O(m \sqrt{n})O(mn​) 的时间复杂度可以过,那么可以考虑用莫队算法。

假设袜子总数为 nnn,color[i]color[i]color[i] 表示第 iii 个位置的袜子颜色。

代码

代码语言:javascript
复制
#include <bits/stdc++.h>
#define ll int
#define MAXN 100000
using namespace std;

ll cnt[MAXN];

// 辗转相除法
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a%b);
}

ll bz;              // 分块大小

// 莫队
struct MO {
    // 查询区间
    struct Query {
        ll l, r;
        ll idx, ntr, dtr;
        bool operator < (Query q) const {
            return l/bz != q.l/bz ? l < q.l : 
                (l/bz) & 1 ? r < q.r : r > q.r;
        }
    };
    ll n, m;            // 数列长度,查询次数
    ll ans;             // 查询答案
    ll color[MAXN];     // 颜色数组
    ll result[MAXN][2]; // 答案数组
    Query query[MAXN];  // 查询区间数组
    // 初始化
    MO() {
        ans = 0;
        memset(query, 0, sizeof(query));
    }
    // 区间长度增一
    void add(ll col) {
        ++cnt[col];
        ans += cnt[col] - 1;
    }
    // 区间长度减一
    void del(ll col) {
        ans -= cnt[col] - 1;
        --cnt[col];
    }
    // 求解答案
    void solver() {
        sort(query, query+m);
        ll l = query[0].l;
        ll r = query[0].l-1;
        for(ll i = 0; i < m; ++i) {
            if(query[i].l >= query[i].r) {
                query[i].ntr = 0;
                query[i].dtr = 1;
                continue;
            }
            while(r < query[i].r) {
                add(color[++r]);
            }
            while(r > query[i].r) {
                del(color[r--]);
            }
            while(l < query[i].l) {
                del(color[l++]);
            }
            while(l > query[i].l) {
                add(color[--l]);
            }
            if(!ans) {
                query[i].ntr = 0;
                query[i].dtr = 1;
            } else {
                ll s = (r-l)%2 ? (r-l+1)/2*(r-l) : (r-l)/2*(r-l+1);
                ll d = gcd(ans, s);
                query[i].ntr = ans / d;
                query[i].dtr = s / d;
            }
        }
        for(ll i = 0; i < m; ++i) {
            result[query[i].idx][0] = query[i].ntr;
            result[query[i].idx][1] = query[i].dtr;
        }
        for(ll i = 0; i < m; ++i) {
            printf("%d/%d\n", result[i][0], result[i][1]);
        }
    }
};

int main()
{
    MO z;
    scanf("%d%d", &z.n, &z.m);
    bz = (int)sqrt(z.n);
    for(ll i = 0; i < z.n; ++i) {
        scanf("%d", &z.color[i]);
    }
    ll l, r;
    for(ll i = 0; i < z.m; ++i) {
        scanf("%d%d", &l, &r);
        z.query[i].l = l-1;
        z.query[i].r = r-1;
        z.query[i].idx = i;
    }
    z.solver();
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 题目
    • 输入输出样例
      • 输入 #1
      • 输出 #1
    • 说明/提示
    • 2. 题解
      • 分析
        • 代码
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档