zoukankan      html  css  js  c++  java
  • CodeForces

    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
    ", 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
    ", res[i]);
    
        return 0;
    
    }
    如果有错误,请指出,谢谢
  • 相关阅读:
    uniApp 实现微信小程序和app视频播放flv格式视频监控
    uniapp 给子组件传值不及时显示
    uni-app 中$refs 在app中无法使用
    使用甘特图
    背景图片加蒙版,里面内容不受影响
    MyBatis 多对一操作
    在Maven项目中使用lombok
    MyBatis使用分页
    Log4j打印日志
    paramiko 下载文件
  • 原文地址:https://www.cnblogs.com/Alruddy/p/7265947.html
Copyright © 2011-2022 走看看