zoukankan      html  css  js  c++  java
  • 【USACO04OPEN】MooFest G

    题目链接

    按$x_i$排序,再扫描线一刷,每次统计左侧的所有影响,即求:$$sum_{i=1}^n sum _{j=1}^i max{v_i,v_j} imes(x_i-x_j)$$

    分类讨论一下,当$v_ige v_j$时,累加$v_i imes x_i-v_i imes x_j$;当$v_i<v_j$时,累加$v_j imes x_i-v_j imes x_j$。

    发现可以用树状数组帮助计算,即在扫描的过程中不断更新:$v_j,x_j,v_j imes x_j,1$关于$v_j$的前缀和$q_v,q_x,q_{vx},q_c$,以及$v_j,v_j imes x_j$的总和$s_v,s_{vx}$。

    那么,每次移动$i$,答案会增长$v_i imes x_i imes q_c-v_i imes q_x+x_i imes(s_v-q_v)-(s_{vx}-q_{vx})$

    程序(100分):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    #define IL inline
    #define RG register
    #define _1 first
    #define _2 second
    using namespace std;
    typedef long long LL;
    const int N=2e4;
    
        int n,ri[N+3];
        LL v[N+3],x[N+3],tv[N+3],tx[N+3];
        
    IL bool cmp(int i,int j){
        return x[i]<x[j];
    }
        
    IL void init(){
        for(int i=1;i<=n;i++)
            ri[i]=i;
        sort(ri+1,ri+n+1,cmp);
        
        memcpy(tv,v,sizeof v);
        memcpy(tx,x,sizeof x);
        for(int i=1;i<=n;i++){
            x[i]=tx[ri[i]];    v[i]=tv[ri[i]];
        }
        
    }
    
        LL vs[N+3],xs[N+3],vxs[N+3],cs[N+3];
        
    IL int lowbit(int x){
        return x&(-x);
    }
    
    IL void mdf(LL *s,int p,LL x){
        for(;p<=N;p+=lowbit(p))
            s[p]+=x;
    }
    
    IL LL qry(LL *s,int p){
        LL ret=0;
        for(;p;p-=lowbit(p))
            ret+=s[p];
        return ret;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&v[i],&x[i]);
            
        init();
        
        memset(vs,0,sizeof vs);
        memset(xs,0,sizeof xs);
        memset(vxs,0,sizeof vxs);
        memset(cs,0,sizeof cs);
        LL ans=0,vxsum=0,vsum=0;
        for(int i=1;i<=n;i++){
            vxsum+=v[i]*x[i];
            vsum+=v[i];
            mdf(vs,v[i],v[i]);
            mdf(xs,v[i],x[i]);
            mdf(vxs,v[i],v[i]*x[i]);
            mdf(cs,v[i],1);
            
            ans+=x[i]*(vsum-qry(vs,v[i]))-(vxsum-qry(vxs,v[i]));
            ans+=qry(cs,v[i])*v[i]*x[i]-v[i]*qry(xs,v[i]);
            
        }
        
        printf("%lld",ans);
    
        return 0;
    
    }
    View Code
  • 相关阅读:
    2,进程----multiprocessing模块介绍
    1,进程----进程理论知识
    对ORM的理解
    对queryset的理解
    个人总结-10-代码测试整合
    个人总结-9-session的使用,十天免登陆
    个人总结-8-重新写注册和登录界面
    个人总结-7- 实现图片在MySQL数据库中的存储,取出以及显示在jsp页面上
    从人机交互看对搜狗输入法的使用感受
    个人总结6-验证码制作总结
  • 原文地址:https://www.cnblogs.com/Hansue/p/12900329.html
Copyright © 2011-2022 走看看