zoukankan      html  css  js  c++  java
  • [国家集训队]小Z的袜子

    Description

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

    Solution

    又水了一道莫队题(练练手感)
    对于询问,以左端点的块为第一关键字,右端点为第二关键字排序
    用一个cnt数组储存从l到r这段区间中的各个颜色的数量
    通过不断加减维护(sum^{m}_{i=1} frac{cnt[color_i]*(cnt[color_i]-1)}{2})
    (frac{(q[i].len)ast (q[i].len-1)}{2})除一个gcd就可以了

    Code

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define MAXN 500005
    struct rec {
    	ll l, r, num, base, x, y;
    } q[MAXN];
    ll n, m, BASE, l, r, ans;
    ll c[MAXN], cnt[MAXN];
    inline ll read() {
    	ll s = 0, w = 1;
    	char c = getchar();
    	for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
    	for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
    	return s * w;
    }
    inline bool cmp1(rec x, rec y) {
    	return (x.base == y.base) ? x.r < y.r : x.base < y.base;
    }
    inline bool cmp2(rec x, rec y) {
    	return x.num < y.num;
    }
    ll gcd(ll x, ll y) {
    	return !y ? x : gcd(y, x % y); 
    } 
    int main() {
    	n = read(), m = read();
    	BASE = sqrt(n);
    	for (register ll i = 1; i <= n; i++)
    		c[i] = read();
    	for (register ll i = 1; i <= m; i++)
    		q[i].l = read(), q[i].r = read(), q[i].num = i, q[i].base = q[i].l / BASE;
    	sort(q + 1, q + m + 1, cmp1);
    	//cnt[0] = 1;
    	l = 1, r = 1, cnt[c[1]]++;
    	for (register ll i = 1; i <= m; i++) {
    		while (r < q[i].r) {
    			r++;
    			ans -= cnt[c[r]] * (cnt[c[r]] - 1);
    			cnt[c[r]]++;
    			ans += cnt[c[r]] * (cnt[c[r]] - 1);
    		}
    		while (r > q[i].r) {
    			ans -= cnt[c[r]] * (cnt[c[r]] - 1);
    			cnt[c[r]]--;
    			ans += cnt[c[r]] * (cnt[c[r]] - 1);
    			r--;
    		}
    		while (l < q[i].l) {
    			ans -= cnt[c[l]] * (cnt[c[l]] - 1);
    			cnt[c[l]]--;
    			ans += cnt[c[l]] * (cnt[c[l]] - 1);
    			l++;
    		}
    		while (l > q[i].l) {
    			l--;
    			ans -= cnt[c[l]] * (cnt[c[l]] - 1);
    			cnt[c[l]]++;
    			ans += cnt[c[l]] * (cnt[c[l]] - 1);
    		}
    		q[i].x = ans;
    		q[i].y = (q[i].r - q[i].l + 1) * (q[i].r - q[i].l);
    	}
    	sort(q + 1, q + m + 1, cmp2);
    	for (register ll i = 1; i <= m; i++)
    		if (q[i].l == q[i].r) cout << 0 << "/" << 1 << endl;
    		else
    			cout << q[i].x / gcd(q[i].x, q[i].y) << "/" << q[i].y / gcd(q[i].x, q[i].y) << endl;
    	return 0;
    }
    
    只要有想见的人,就不是孤身一人了。
  • 相关阅读:
    服务器开启超线程
    redhat用kickstart.cfg自动安装后,挂载ISO镜像并从中拷贝文件
    关于网卡特性TSO、UFO、GSO、LRO、GRO
    Linux 网卡特性配置ethtool详解
    SecureCRT设置标签显示标题
    关闭SecureCRT的声音
    SecureCRT设置Vim显示颜色
    centos关闭swap分区
    制作CentOS7.6 自动安装ISO镜像光盘
    带阵列卡的机器打开磁盘cache
  • 原文地址:https://www.cnblogs.com/Agakiss/p/11784643.html
Copyright © 2011-2022 走看看