大视野2038 小z的袜子 莫队算法
2015-09-26 10:21
225 查看
[code]#include <cstdio> #include <iostream> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define LL long long int n,m; int a[500005]; struct node{ int l,r; int id; }Q[500005]; LL gcd(LL a,LL b){ return b==0?a:gcd(b,a%b); } struct q{ LL a,b; void huajian(){ LL d = gcd(a,b); a /= d; b /= d; } }ans[500005]; int num[500005]; int Un; bool cmp(node a,node b){ if(a.l/Un != b.l/Un) return a.l/Un < b.l/Un; else return a.r < b.r; } void work(){ LL temp = 0; memset(num,0,sizeof(num)); int l = 1; int r = 0; for(int i = 0;i < m;i++){ while(r < Q[i].r){ r ++; temp -= (LL) num[a[r]] * num[a[r]]; num[a[r]] ++; temp += (LL) num[a[r]] * num[a[r]]; } while(r > Q[i].r){ temp -= (LL) num[a[r]] * num[a[r]]; num[a[r]] --; temp += (LL) num[a[r]] * num[a[r]]; r--; } while(l < Q[i].l){ temp -= (LL) num[a[l]] * num[a[l]]; num[a[l]] --; temp += (LL) num[a[l]] * num[a[l]]; l++; } while(l > Q[i].l){ l --; temp -= (LL) num[a[l]] * num[a[l]]; num[a[l]] ++; temp += (LL) num[a[l]] * num[a[l]]; } ans[Q[i].id].a = temp - (r-l+1); ans[Q[i].id].b = (LL)(r-l+1)*(r-l); ans[Q[i].id].huajian(); } } int main(){ while(cin >> n >> m){ for(int i = 1;i <= n;i++){ scanf("%d",&a[i]); } for(int i = 0;i < m;i++){ int x,y; scanf("%d%d",&x,&y); Q[i].l = x; Q[i].r = y; Q[i].id = i; } Un = (int)sqrt(n); sort(Q,Q+m,cmp); work(); for(int i = 0;i < m;i++){ printf("%lld/%lld\n",ans[i].a,ans[i].b); } } return 0; }
我对莫队算法的理解就是对查询进行排序然后合理的暴力,也就是合理的组织一下查询的顺利让前面的暴力对后面的暴力有一定的贡献,这样就能节省一点时间
相关文章推荐
- HDU - 1176 免费馅饼(DP)
- javascript闪烁图片
- pe创建激活administrator后消除问题,删除用户问题
- PAT(甲级)1050
- JAVA --解压缩
- 新世界PT850/PT853检查用友机对接T1交易宝
- PAT(甲级)1049
- leetcode 080 Remove Duplicates from Sorted Array II(难易度:Medium)
- Bios工程师手边事—battery
- 自定义的RPC的Java实现
- JAVA-文件压缩
- 大道至简读后感
- MVC学习笔记---各种上下文context
- WPF 中图标路径问题
- jqery实现10X10的表格,双击消失
- WPF 中图标路径问题
- PAT(甲级)1048
- C语言复习day2
- uvalive 4671 - K-neighbor substrings 快速傅利叶变换
- PAT(甲级)1047