zoukankan      html  css  js  c++  java
  • 【序列莫队】BZOJ2038- [2009国家集训队]小Z的袜子(hose)

    【题目大意】
    给出1-N只袜子的颜色,多次询问L-R中选出一双同色袜子的概率。

    【思路】

    裸莫队。基本的莫队步骤:
    ①分组(每组大小为根号sqrt(n),共sqrt(n)组)
    ②排序(左边界分组,右边界在组内按大小排序)
    ③暴力转移

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 const int MAXN=50000+50;
     8 typedef long long ll;
     9 struct node
    10 {
    11     int l,r,id,pos;
    12     ll ansa,ansb;
    13 };
    14 int n,m,c[MAXN];
    15 ll ans=0,s[MAXN];
    16 ll sqr(ll x){return x*x;}  
    17 node q[MAXN];
    18  
    19 ll gcd(ll a,ll b)
    20 {
    21     if (b==0) return a;
    22         else return gcd(b,a%b);
    23 }
    24  
    25 bool cmp(node a,node b)
    26 {
    27     if (a.pos==b.pos) return (a.r<b.r);
    28         else return (a.pos<b.pos);
    29 }
    30  
    31 bool cmp_id(node a,node b)
    32 {
    33     return (a.id<b.id);
    34 }
    35  
    36 void update(int x,int delta)
    37 {
    38     ans-=sqr(s[c[x]]);
    39     s[c[x]]+=delta;
    40     ans+=sqr(s[c[x]]);
    41 }
    42  
    43 void init()
    44 {
    45     memset(s,0,sizeof(s));
    46     memset(c,0,sizeof(c));
    47     scanf("%d%d",&n,&m);
    48     for (int i=1;i<=n;i++) scanf("%d",&c[i]);
    49     int block=int(sqrt(n));
    50     for (int i=0;i<m;i++)
    51     {
    52         scanf("%d%d",&q[i].l,&q[i].r);
    53         q[i].id=i;
    54         q[i].pos=(q[i].l-1)/block+1;
    55     }
    56     sort(q,q+m,cmp);
    57 }
    58  
    59 void solve()
    60 {
    61     int l=1,r=1;
    62     s[c[1]]=1,ans=sqr(s[c[1]]);
    63     for (int t=0;t<m;t++)
    64     {
    65         for (;r<q[t].r;r++) update(r+1,1);
    66         for (;r>q[t].r;r--) update(r,-1);
    67         for (;l<q[t].l;l++) update(l,-1);
    68         for (;l>q[t].l;l--) update(l-1,1);
    69         if (l==r)
    70         {
    71             q[t].l=0;q[t].r=1;
    72             continue;
    73         }
    74         q[t].ansa=ans-(r-l+1);
    75         q[t].ansb=(ll)(r-l+1)*(r-l);
    76         ll minx=min(q[t].ansa,q[t].ansb),maxx=max(q[t].ansa,q[t].ansb);
    77         ll k=gcd(maxx,minx);
    78         q[t].ansa/=k,q[t].ansb/=k;
    79     }
    80 }
    81  
    82 void print()
    83 {
    84     sort(q,q+m,cmp_id);
    85     for (int i=0;i<m;i++) printf("%lld/%lld
    ",q[i].ansa,q[i].ansb);
    86 }
    87  
    88 int main() 
    89 {
    90     init();
    91     solve();
    92     print(); 
    93     return 0;
    94 }
  • 相关阅读:
    antd vue如何在父组件里打开子组件(子组件是个模态框)?
    webpack知识点整理
    JavaScript中常用的方法汇总,全部整理好了,一定要收藏!
    从地址栏里面获取参数的值
    何为垫片?垫片是一种什么概念在js中?
    async 与 await使用
    纯手撸Promise
    如何使用 Promise?
    Notification 浏览器桌面通知的使用
    学习骨架屏(Skeleton Screens)技术
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5679659.html
Copyright © 2011-2022 走看看