• P2345 奶牛集会


      这道题我感觉评成紫题并不夸张,这比某些紫题思维含量高多了……反正我好久才想明白怎么做……

      其实,这道题就是求这个式子所有的 “ max{ Vi ; Vj } × | Xi − Xj | ” 之和。由于n的范围20000,显然 n2是过不了的。(但是洛谷数据问题,n2能过,我也是醉了……)

      那我们分析一下:对于一对 i , j ,能做出贡献的只有大的 v 所以我们对于一个 v ,一定是找比 v 小的去累计贡献,所以我们要从小到大枚举 v 。

      那我们考虑对于这样的一个 v 的贡献:

      20000 ————B段———— v —————A段——— 1

      一下考虑都是小于 v 的其他 v ' 。

      对于A段和B段,我们发现想求贡献就需要知道A 、B段的距离和,和点的个数。这两个用线段树维护即可,那么我们的问题就在如何锁定 v ' 。

      其实这个很简答,在从小打到枚举 v 的同时处理线段树,这样我们每一次考虑的就是小于 v 的 v ' 了。

      这道题真的挺好,值得一做。

      北京市第三区交委提醒您:做题不long long,亲人两行泪。

      代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    #define maxn 80000
    #define int long long
    #define ls now<<1
    #define rs now<<1|1
    struct node
    {
        int v,x;
    } q[maxn];
    int l[maxn],r[maxn],x[maxn],num[maxn];
    int n,ans;
    void up(int now)
    {
        num[now]=num[ls]+num[rs];
        x[now]=x[ls]+x[rs];
    }
    bool cmp(node a,node b)
    {
        return a.v<b.v;
    }
    void build(int now,int L,int R)
    {
        l[now]=L;
        r[now]=R;
        if(L==R) return ;
        int mid=(L+R)>>1;
        build(ls,L,mid);
        build(rs,mid+1,R);
    }
    void update(int now,int id)
    {
        if(l[now]==r[now]&&l[now]==id)
        {
            num[now]++;
            x[now]=id;
            return ;
        }
        int mid=(l[now]+r[now])>>1;
        if(id<=mid) update(ls,id);
        else update(rs,id);
        up(now);
    }
    int query_num(int now,int L,int R)
    {
        if(l[now]==L&&r[now]==R)
            return num[now];
        int mid=(l[now]+r[now])>>1;
        if(R<=mid) return query_num(ls,L,R);
        else if(L>mid) return query_num(rs,L,R);
        else return query_num(ls,L,mid)+query_num(rs,mid+1,R);
    }
    int query_sum(int now,int L,int R)
    {
        if(l[now]==L&&r[now]==R)
            return x[now];
        int mid=(l[now]+r[now])>>1;
        if(R<=mid) return query_sum(ls,L,R);
        else if(L>mid) return query_sum(rs,L,R);
        else return query_sum(ls,L,mid)+query_sum(rs,mid+1,R);
    }
    void solve()
    {
        for(int i=1;i<=n;i++)
        {
            int x=q[i].x;
            int v=q[i].v;
            ans+=v*(query_num(1,1,x)*x-query_sum(1,1,x))
            +v*(query_sum(1,x,20000)-query_num(1,x,20000)*x);
            update(1,x);
        }
    }
    main()
    {
        scanf("%lld",&n);
        for(int i=1; i<=n; i++)
            scanf("%lld%lld",&q[i].v,&q[i].x);
        sort(q+1,q+n+1,cmp);
        build(1,1,20000);
        solve();
        printf("%lld
    ",ans);
        return 0;
    }

      

  • 相关阅读:
    Selector空轮询处理(转载)
    使用SHOW binlog events查看binlog内容
    netty 3.x 实现http server和遇到的坑
    Tomcat7启动分析(三)Digester的使用(转载)
    MySQL · 引擎特性 · 基于InnoDB的物理复制实现(转载)
    InnoDB多版本(MVCC)实现简要分析(转载)
    MySQL数据库事务各隔离级别加锁情况--read committed && MVCC(转载)
    第 4 章 序列和字符串
    BLAST在Windows系统中本地化
    Sublime text3 创建html模板
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10941105.html
Copyright © 2020-2023  润新知