标签: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 / b 15 struct node 16 { 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 else 58 { 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 }
标签:opera void names 莫队 += 算法 更新 main 离线操作
原文地址:https://www.cnblogs.com/ivan-count/p/9407943.html