zoukankan      html  css  js  c++  java
  • BZOJ 2038: [2009国家集训队]小Z的袜子(hose)(莫队算法)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2038

    题意:

    思路:

    简单介绍一下莫队算法,使用这个算法需要满足一些条件:
    ①区间不修改

    ②离线处理

    ③在知道了[l,r]的答案后,在此基础上能在比较快地在O(1)得到相邻区间[l+1,r]、[l-1,r]、[l,r-1]、[l,r+1]的答案

    处理过程:

    • 首先对原序列进行分块,√n块每块√n个;
    • 然后对所有查询的区间[l,r]进行排序,首先按l所在的块序号升序排序,如果一样就按r升序排序;
    • 之后就一些加加减减
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn=50000+5;
    16 
    17 int n,m,unit;
    18 ll tmp,num[maxn];
    19 int a[maxn];
    20 
    21 struct node
    22 {
    23     int l,r,id;
    24 }query[maxn];
    25 
    26 ll gcd(ll a,ll b)
    27 {
    28     return b==0?a:(gcd(b,a%b));
    29 }
    30 
    31 struct Node
    32 {
    33     ll a,b;
    34     void reduce()
    35     {
    36         ll g=gcd(a,b);
    37         a/=g;
    38         b/=g;
    39     }
    40 }ans[maxn];
    41 
    42 bool cmp(node a, node b)
    43 {
    44     if(a.l/unit != b.l/unit)  return a.l/unit<b.l/unit;
    45     else return a.r<b.r;
    46 }
    47 
    48 void update(int x, int d)
    49 {
    50     tmp-=num[a[x]]*num[a[x]];
    51     num[a[x]]+=d;
    52     tmp+=num[a[x]]*num[a[x]];
    53 }
    54 
    55 int main()
    56 {
    57     //freopen("in.txt","r",stdin);
    58     scanf("%d%d",&n,&m);
    59     for(int i=1;i<=n;i++)  scanf("%d",&a[i]);
    60     for(int i=1;i<=m;i++)
    61     {
    62         scanf("%d%d",&query[i].l,&query[i].r);
    63         query[i].id=i;
    64     }
    65     unit=(int)sqrt(n);
    66     sort(query+1,query+m+1,cmp);
    67     tmp=0;
    68     memset(num,0,sizeof(num));
    69     int l=1,r=0;
    70     for(int i=1;i<=m;i++)
    71     {
    72         while(r<query[i].r)   r++,update(r,1);
    73         while(r>query[i].r)   update(r,-1),r--;
    74         while(l<query[i].l)   update(l,-1),l++;
    75         while(l>query[i].l)   l--,update(l,1);
    76         ans[query[i].id].a=tmp-(r-l+1);
    77         ans[query[i].id].b=(ll)(r-l+1)*(r-l);
    78         ans[query[i].id].reduce();
    79     }
    80     for(int i=1;i<=m;i++)
    81     {
    82         printf("%lld/%lld
    ",ans[i].a,ans[i].b);
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    定时日志清理
    python ros 订阅robot_pose获取机器人位置
    python ros 重新设置机器人的位置
    c 宏的定义
    dos与unix系统的格式转化
    robot_pose的类型
    ROS编译时(catkin_make)找不到bullet,Could NOT find Bullet (missing: BULLET_DYNAMICS_LIBRARY
    python 压缩tar 包
    python 文件分割
    python 千位分隔符,
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7446546.html
Copyright © 2011-2022 走看看