首页 > 代码库 > CodeForces - 86D 莫队算法
CodeForces - 86D 莫队算法
http://codeforces.com/problemset/problem/86/D
莫队算法就是调整查询的顺序,然后暴力求解。
每回可以通过现有区间解ans(l,r)得到区间(l+1,r),(l-1,r),(l,r+1),(l,r-1)的区间解。
调整方式http://blog.csdn.net/bossup/article/details/39236275
这题比那个还要简单,查询的是K^2*Z,很清楚就是莫队算法,然而做的时候没有学过,回来补题补到
关键是我一直没明白为什么重载小于号运算符会比重写比较函数要费时间,运算符重载挂在第44个例子,交了10多遍。
Orz,Orz 又交了几遍,一样的代码有时会跑不出来,然后又在比较函数上优化,勉强能看了。
不过还是弱到不知道那个2s钟怎么跑的。。。
代码最终版本
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <math.h> using namespace std; typedef long long LL; const int N = 2e5 + 5; const int MAXN = 1e6 + 20; LL cnt[MAXN]; int pos[N]; LL ans = 0; int sqr; struct query { int l,r,id; }; query q[N]; int a[N]; LL res[N]; bool cmp(query a, query b) { if(pos[a.id] == pos[b.id]) return a.r < b.r; return pos[a.id] < pos[b.id]; } void update(int x, int d) { ans += cnt[a[x]]*2*d*a[x] + a[x]; cnt[a[x]] += d; } void init() { memset(cnt, 0, sizeof(cnt)); memset(a, 0, sizeof(a)); memset(q, 0, sizeof(q)); } int n, m, l ,r; int main( ) { // freopen("D.in", "r", stdin); init(); scanf("%d%d", &n, &m); sqr = sqrt(m); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 1; i <= m; i++) { scanf("%d%d", &q[i].l, &q[i].r); pos[i] = q[i].l/sqr; q[i].id = i; } sort(q+1, q+m+1, cmp); ans = 0; int pl = 1, pr = 0; for(int i = 1; i <= m; i++) { int id = q[i].id; while(pl < q[i].l) { update(pl, -1); pl++; } while(pl > q[i].l) { pl--; update(pl, 1); } while(pr < q[i].r) { pr++; update(pr, 1); } while(pr > q[i].r) { update(pr, -1); pr--; } res[id] = ans; } for(int i = 1; i <= m; i++) printf("%I64d\n", res[i]); return 0; }
之前版本:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <math.h> using namespace std; typedef long long LL; const int N = 2e5 + 5; const int MAXN = 1e6 + 20; LL cnt[MAXN]; LL ans = 0; int sqr; struct query { int l,r,id; }; query q[N]; int a[N]; LL res[N]; bool cmp(query a, query b) { if((a.l-1)/sqr == (b.l-1)/sqr) return a.r < b.r; return (a.l-1)/sqr < (b.l-1)/sqr; } void update(int x, int d) { ans -= cnt[a[x]]*cnt[a[x]]*a[x]; cnt[a[x]] += d; ans += cnt[a[x]]*cnt[a[x]]*a[x]; } void init() { memset(cnt, 0, sizeof(cnt)); memset(a, 0, sizeof(a)); memset(q, 0, sizeof(q)); } int n, m, l ,r; int main( ) { // freopen("D.in", "r", stdin); init(); scanf("%d%d", &n, &m); sqr = sqrt(m); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } for(int i = 1; i <= m; i++) { scanf("%d%d", &q[i].l, &q[i].r); q[i].id = i; } sort(q+1, q+m+1, cmp); ans = 0; int pl = 1, pr = 0; for(int i = 1; i <= m; i++) { int id = q[i].id; while(pl < q[i].l) { update(pl, -1); pl++; } while(pl > q[i].l) { pl--; update(pl, 1); } while(pr < q[i].r) { pr++; update(pr, 1); } while(pr > q[i].r) { update(pr, -1); pr--; } res[id] = ans; } for(int i = 1; i <= m; i++) printf("%I64d\n", res[i]); return 0; }
CodeForces - 86D 莫队算法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。