莫隊演算法

來源:互聯網
上載者:User

標籤:opera   void   names   莫隊   +=   演算法   更新   main   離線操作   

原理

1、離線操作。

2、劃分成若干塊,將區間先按塊排序,塊內按區間右邊界排序。塊大小一般為sqrt(n)。

3、按照排序後的區間進行操作,不斷進行區間轉移,更新答案。

題目

1、小Z的襪子(hose) HYSBZ - 2038

  題意:有n只襪子,求區間內顏色相同的兩隻襪子的機率。

  思路:對於區間[l,r],其機率為sum(cnt[i]*(cnt[i-1])|i∈val[l,..,r])/[(r-l+1)*(r-l)]。按照莫隊的思想更新分子即可。

 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 const int maxn = 5e5 + 10; 7 const int maxm = 5e5 + 10; 8 int n, m; 9 int unit_len;10 int be[maxn];//記錄下標L屬於哪一個分塊11 int val[maxn];12 int cnt[maxn];13 long long  ans;14 long long ansa[maxn],ansb[maxn]; //答案a / b15 struct node16 {17     int l, r,id;//區間[l,r]、輸入順序18     friend bool operator<(const node&n1, const node&n2)19     {20         if (be[n1.l] == be[n2.l]) return n1.r < n2.r;21         else return n1.l < n2.l;22     }23 }qs[maxm];24 long long GCD(long long a, long long b)25 {26     if (a < b) swap(a, b);27     while (b)28     {29         long long tmp = a % b;30         a = b;31         b = tmp;32     }33     return a;34 }35 long long cal(int x)36 {37     return 1ll * x*(x - 1);38 }39 void update(int pos, int v)40 {41     ans -= cal(cnt[val[pos]]);42     cnt[val[pos]] += v;43     ans += cal(cnt[val[pos]]);44 }45 void solve()46 {47     int l = 1, r = 0;48     ans = 0;49     for (int i = 1; i <= m; i++)50     {51         int id = qs[i].id;52         while (r < qs[i].r) update(r + 1, 1), r++;53         while (r > qs[i].r) update(r, -1),r--;54         while (l < qs[i].l) update(l, -1), l++;55         while (l > qs[i].l) update(l - 1, 1), l--;56         if (ans == 0) ansa[id] = 0, ansb[id] = 1;57         else58         {59             ansb[id]= cal(qs[i].r - qs[i].l + 1);60             ansa[id]= ans;61             long long gcd = GCD(ansa[id],ansb[id]);62             ansa[id]/= gcd;63             ansb[id] /= gcd;64         }65     }66 }67 int main()68 {69     while (~scanf("%d%d", &n, &m))70     {71         unit_len = sqrt(n);72         for (int i = 1; i <= n; i++) scanf("%d", &val[i]);73         for (int i = 1; i <= n; i++) be[i] = i / unit_len + 1;74         for (int i = 1; i <= m; i++) scanf("%d%d", &qs[i].l, &qs[i].r),qs[i].id=i;75         sort(qs + 1, qs + 1 + m);76         solve();77         for (int i = 1; i <= m; i++)78         {79             printf("%lld/%lld\n", ansa[i], ansb[i]);80         }81     }82 83 84     return 0;85 }
View Code

 

莫隊演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.