清橙A1206 莫队

清橙A1206
题目链接:
http://www.tsinsen.com/A1206
题意:
中文题
思路:
莫队算法入门题。
从昨晚上看到现在也是有够笨的……
莫队算法有一个引入的知识是曼哈顿最小生成树,不过这个好像比较难的样子,因为可能会用到平衡树或者线段树。只需要知道一个结论就可以,那就是对于一个二维平面图中一些点,如果要构造一个曼哈顿距离的最小生成树,那么选取边的时候对于一个点只需要最多选取8条边(O(8*n)),而不是和所有的点建立边然后求最小生成树O(n*n)
详见http://blog.csdn.net/huzecong/article/details/8576908

莫队算法借用了曼哈顿最小生成树的思想。
莫队算法用于求对一些区间的询问,那么把一个个询问看成二维平面图上的点[l,r],然后就可以用类似曼哈顿最小生成树的知识来解了。也就是说,如果要求的某个点的值,找一个最近的点去求,消耗最小。整体更新的消耗,就是曼哈顿最小生成树的边的大小。

当然上面不知道也可以,因为具体实现的时候并没有用平衡树或者线段树这么高端的算法维护。采用一种分块处理的办法,即把所有点分成sqrt(n)块,按照块排序后在再按照右端点排序,然后暴力求解。可以证明这样暴力复杂度比较小。
详见http://blog.csdn.net/bossup/article/details/39236275

枉我看这么久,说白了就是暴力啊……
源码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL long long
const int MAXN = 50000 + 5;
int pos[MAXN];
struct Q
{
    int l, r;
    int id;
}q[MAXN];
bool cmp1(Q a, Q b)
{
    if(pos[a.l] == pos[b.l]) return a.r < b.r;
    else return a.l < b.l;
}
bool cmp2(Q a, Q b){return a.id < b.id;}
int data[MAXN];
LL num[MAXN];
int blocksize;
LL cnt;
LL up[MAXN], dw[MAXN];
void update(int u, int v)
{
    cnt -= num[u] * num[u];
    num[u] += v;
    cnt += num[u] * num[u];
}
int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m) != EOF){
        memset(num, 0, sizeof(num));
        blocksize = sqrt(1.0 * n);
        for(int i = 1 ; i <= n ; i++){
            scanf("%d", &data[i]);
            pos[i] = (i - 1) / blocksize;
        }
        for(int i = 0 ; i < m ; i++){
            scanf("%d%d", &q[i].l, &q[i].r);
            q[i].id = i;
        }
        sort(q, q + m, cmp1);
        int curr = 0, curl = 1;
        cnt = 0;
        for(int i = 0 ; i < m ; i++){
            if(q[i].l == q[i].r){
                up[q[i].id] = 0;
                dw[q[i].id] = 1;
                continue;
            }
            if(curr != q[i].r){
                for(int j = curr + 1; j <= q[i].r ; j++) update(data[j], 1);
                for(int j = curr ; j > q[i].r ; j--) update(data[j], -1);
            }
            if(curl != q[i].l){
                for(int j = curl ; j < q[i].l ; j++) update(data[j], -1);
                for(int j = curl - 1 ; j >= q[i].l ; j--) update(data[j], 1);
            }
            curr = q[i].r, curl = q[i].l;
            up[q[i].id] = cnt - (q[i].r - q[i].l + 1);
            dw[q[i].id] = (LL)(q[i].r - q[i].l + 1) * (q[i].r - q[i].l);
            LL temp = __gcd(up[q[i].id], dw[q[i].id]);
            up[q[i].id] /= temp;
            dw[q[i].id] /= temp;
//            printf("i = %d, ans = %I64d, q[i].id = %d, l = %d, r = %d\n", i, cnt, q[i].id, q[i].l, q[i].r);
        }
        for(int i = 0 ; i < m ; i++)
            printf("%I64d/%I64d\n", up[i], dw[i]);
    }
    return 0;
}
Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值