小z的袜子

来源:互联网 发布:js树状图 饼图插件 编辑:程序博客网 时间:2024/03/29 01:06

题解

一.链接:http://www.cnblogs.com/kuangbin/archive/2013/08/16/3263483.html

把1~n分成sqrt(n)段。


unit = sqrt(n)


m个查询先按照第几个块排序,再按照 R排序。


#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int MAXN = 50010;
const int MAXM = 50010;
struct Query
{
    int L,R,id;
}node[MAXM];


long long gcd(long long a,long long b)
 {
    if(b == 0) return a;
     return gcd(b,a%b);
}


  struct Ans
 {
    long long a,b;//分数a/b
    void reduce()//分数化简
     {
         long long d = gcd(a,b);
         a /= d; b /= d;
    }
 }ans[MAXM];
 
int a[MAXN];//每个袜子的颜色; 
int num[MAXN];//区域内这种颜色的数量; 
int n,m,unit;
 
bool cmp(Query a,Query b)
{
    if(a.L/unit != b.L/unit)return a.L/unit < b.L/unit;
     else return a.R < b.R;
}
  
void work()
 {
      long long temp = 0;
      memset(num,0,sizeof(num));
      int L = 1;
      int R = 0;
      for(int i = 0;i < m;i++)
      {
 //n*(n-1)==n*n-n,这里二不除了;减n留到最后; 
          while(R < node[i].R)
          {
              R++;
              temp -= (long long)num[a[R]]*num[a[R]]; 
              num[a[R]]++;
              temp += (long long)num[a[R]]*num[a[R]];
          }
          while(R > node[i].R)
          {
             temp -= (long long)num[a[R]]*num[a[R]];
             num[a[R]]--;
             temp += (long long)num[a[R]]*num[a[R]];
             R--;
          }
          
          while(L < node[i].L)
          {
              temp -= (long long)num[a[L]]*num[a[L]];
              num[a[L]]--;
              temp += (long long)num[a[L]]*num[a[L]];
              L++;
          }
         while(L > node[i].L)
          {
             L--;
             temp -= (long long)num[a[L]]*num[a[L]];
             num[a[L]]++;
             temp += (long long)num[a[L]]*num[a[L]];
          }
          
         ans[node[i].id].a = temp - (R-L+1);
         ans[node[i].id].b = (long long)(R-L+1)*(R-L);
         ans[node[i].id].reduce();
      }
}
 


int main()
{
     freopen("sock.in","r",stdin);
     freopen("sock.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++)
             scanf("%d",&a[i]);
        for(int i = 0;i < m;i++)
        {
             node[i].id = i;
             scanf("%d%d",&node[i].L,&node[i].R);
        }
        unit = (int)sqrt(n);
        sort(node,node+m,cmp);//排序; 
        work();
        for(int i = 0;i < m;i++) printf("%I64d/%I64d\n",ans[i].a,ans[i].b);
    return 0;
}

二.链接:http://blog.csdn.net/huzecong/article/details/8576908



0 0