简单莫对算法 --- 离线处理所有询问
来源:互联网 发布:测绘数据泄密案例 编辑:程序博客网 时间:2024/05/18 12:36
思想: 先把所有的询问全部记下来. 然后通过一定的技巧使得暴力的复杂度不高, 从而达到目的, 一次性全部输出答案.
以这两道模板题来说明一下它如何暴力的更漂亮.
复杂度为 O n ^ 3/2 ; (2e5是可以跑的)
小Z的袜子
AC Code
#include <bits/stdc++.h>#define ll long longusing namespace std;const int maxn = 5e4+5;int a[maxn];ll fz[maxn],fm[maxn];int times[maxn];int block;struct node{ int l,r,id;}s[maxn];bool cmp(node x,node y){ if(x.l/block==y.l/block) return x.r<y.r; return x.l<y.l;}int main(){ int n,q; scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=q; i++){ scanf("%d%d",&s[i].l,&s[i].r); s[i].id=i; } block=(int)sqrt(n+0.5); sort(s+1,s+q+1,cmp); int l = 1 , r = 1; //范围是[l,r); ll sum = 0; for(int i=1;i<=q;i++){ while(l < s[i].l){ times[a[l]]--; sum -= times[a[l]] ; //唯一需要点推理的就是多加一次少加一次对sum总体的影响. 即times怎么变. l++; } while(l > s[i].l){ l--; sum += times[a[l]]; times[a[l]]++; } while(r < s[i].r+1){ //所以注意下范围然后就可以写出来了. sum += times[a[r]]; times[a[r]]++; r++; } while(r > s[i].r+1){ r--; times[a[r]]--; sum -= times[a[r]]; } ll len = s[i].r+1-s[i].l; ll t = __gcd(len*(len-1)/2,sum); fz[s[i].id] = sum/t; fm[s[i].id] = len*(len-1)/2/t ; } for(int i=1;i<=q;i++){ printf("%lld/%lld\n",fz[i],fm[i]); }}
Powerful Array
#include <bits/stdc++.h>#define ll long longusing namespace std;const int maxn = 2e5+5;int a[maxn];ll res[maxn];int times[maxn * 5];int block;struct node{ int l,r,id;}s[maxn];bool cmp(node x,node y){ if(x.l/block==y.l/block) return x.r<y.r; return x.l<y.l;}int main(){ int n,q; scanf("%d%d",&n,&q); for(int i=1; i<=n; i++) scanf("%d",&a[i]); for(int i=1; i<=q; i++){ scanf("%d%d",&s[i].l,&s[i].r); s[i].id=i; } block=(int)sqrt(n+0.5); sort(s+1,s+1+q,cmp); int l = 1 , r = 1; //范围是[l,r); ll sum = 0; for(int i=1;i<=q;i++){ while(l < s[i].l){ times[a[l]]--; sum -= a[l] * (times[a[l]] * 2 + 1); l++; } while(l > s[i].l){ l--; sum += a[l] * (times[a[l]] * 2 + 1); times[a[l]]++; } while(r < s[i].r+1){ //所以注意下范围然后就可以写出来了. sum += a[r] * (times[a[r]] * 2 + 1); times[a[r]]++; r++; } while(r > s[i].r+1){ r--; times[a[r]]--; sum -= a[r] * (times[a[r]] * 2 + 1); } res[s[i].id] = sum; } for(int i=1;i<=q;i++) printf("%lld\n",res[i]);}
阅读全文
0 0
- 简单莫对算法 --- 离线处理所有询问
- BestCoder Round #36(Trees-离线处理询问)
- POJ 2761 Feed the dogs (SBT+离线处理询问)
- 【APIO2008T1】珠链交换器-离线处理询问+模拟
- 离线处理(线段树|树状数组)| 莫对算法 —— HDU 4638 Group
- HDU 5381 The sum of gcd 询问区间内所有子区间的GCD和 [莫队算法]
- hdu4638 莫对算法 离线区间查询(非更新)
- 对“求数组中所有和为某固定数的所有数对”的算法的简单思考
- HDU 3333 & 3874 (线段树+离线询问)
- BZOJ 3781 小B的询问 莫队算法
- BZOJ 3781 小B的询问 莫队算法
- bzoj3781: 小B的询问 莫队算法
- BZOJ 3781 小B的询问 序列莫队算法
- 3781: 小B的询问 莫队算法
- 【BZOJ3781】小B的询问【莫队算法】
- 区间询问凶器——莫队算法~
- bzoj 3781: 小B的询问 莫队算法+分块
- BZOJ 3781: 小B的询问 莫队算法
- 二叉树的实现(一)
- 欢迎使用CSDN-markdown编辑器
- 第八章 matplotlib画图
- STL容器的总结
- 正则表达式30分钟入门教程
- 简单莫对算法 --- 离线处理所有询问
- Blog项目 —上集
- 创建新表时的导出表sql
- 关于hibernate一级缓存
- Linux ubuntu 安装MySql
- Spring-Boot初学之配置文件application.properties(数据源配置)
- leetcode题解-206. Reverse Linked List
- 将博客搬至CSDN
- Linux下的静态库与动态库