zoukankan      html  css  js  c++  java
  • 【bzoj2038-小z的袜子】莫队算法

    莫队例题。

    莫队学习:https://www.cnblogs.com/Paul-Guderian/p/6933799.html

    本题 分子是sigma(c(sum[a[i]],2)),分母是sigma(l-r+1,2); 维护分子和即可。

    莫队适用范围:离线,区间,区间转移到下一格O(1)。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 
     9 const int N=50010;
    10 typedef long long LL;
    11 int n,m,sq,a[N];
    12 LL ans,gcd,sum[N];
    13 struct node{
    14     int l,r,k,id;
    15     LL fz,fm;
    16 };
    17 node b[N];
    18 
    19 int maxx(int x,int y){return x>y?x:y;}
    20 bool cmp1(node x,node y)
    21 {
    22     if(x.k==y.k) return x.r<y.r;
    23     return x.l<y.l;
    24 }
    25 bool cmp2(node x,node y)
    26 {
    27     return x.id<y.id;
    28 }
    29 void revise(int x,int d)
    30 {
    31     ans-=sum[a[x]]*(sum[a[x]]-1)/2;
    32     sum[a[x]]+=d;
    33     ans+=sum[a[x]]*(sum[a[x]]-1)/2;
    34 }
    35 LL getgcd(LL a,LL b)
    36 {
    37     return b?getgcd(b,a%b):a;
    38 }
    39 
    40 int main()
    41 {
    42     freopen("a.in","r",stdin);
    43     freopen("a.out","w",stdout);
    44     scanf("%d%d",&n,&m);sq=sqrt(n);
    45     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    46     for(int i=1;i<=m;i++)
    47     {
    48         scanf("%d%d",&b[i].l,&b[i].r);
    49         b[i].k=b[i].l/sq;
    50         b[i].id=i;
    51     }
    52     sort(b+1,b+m+1,cmp1);
    53     memset(sum,0,sizeof(sum));
    54     int l=1,r=1;sum[a[1]]=1;ans=0;
    55     for(int i=1;i<=m;i++)
    56     {
    57         while(l<b[i].l) {revise(l,-1);l++;}
    58         while(l>b[i].l) {revise(l-1,1);l--;}
    59         while(r<b[i].r) {revise(r+1,1);r++;}
    60         while(r>b[i].r) {revise(r,-1);r--;}
    61         b[i].fz=ans;b[i].fm=((LL)(b[i].r-b[i].l+1))*((LL)(b[i].r-b[i].l))/2;
    62         gcd=getgcd(b[i].fz,b[i].fm);
    63         b[i].fz/=gcd;b[i].fm/=gcd;
    64         if(b[i].fz==0) b[i].fm=1;
    65     }
    66     sort(b+1,b+m+1,cmp2);
    67     for(int i=1;i<=m;i++)
    68     {
    69         printf("%lld/%lld
    ",b[i].fz,b[i].fm);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    转(一致性哈希算法(consistent hashing))
    【CMD】findstr命令
    【Android】 Sqlite3 not found
    【Android】Sqlite3命令详解
    数据结构-哈夫曼树
    数据结构-线索化二叉树
    【原创】解决国内Android SDK无法更新问题更新
    数据结构-插入排序之希尔排序
    数据结构-插入排序之直接插入排序
    数据结构-二叉树的遍历
  • 原文地址:https://www.cnblogs.com/KonjakJuruo/p/9339087.html
Copyright © 2011-2022 走看看