• 2020浙江省赛E Easy DP Problem(主席树)


    对于这个dp转移方程,我们观察到的是每个点都从左上方转移或者上方转移。

    如果从左上方转移,那么多了一个b[i],可见我们对于每一行在第几列,就能获得几个b[i],那么这其实就是求区间的前k大值和

    这就是主席树模板题

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=2e5+10;
    int rt[N],idx;
    ll pre[N];
    int a[N];
    vector<int> num;
    struct node{
        int l,r;
        int cnt;
        ll sum;
        ll d;
    }tr[N*40];
    int n;
    void init(){
        pre[1]=1;
        for(ll i=2;i<=100005;i++)
            pre[i]=pre[i-1]+i*i;
    }
    void build(int &p,int l,int r){
        p=++idx;
        if(l==r){
            return ;
        }
        int mid=l+r>>1;
        build(tr[p].l,l,mid);
        build(tr[p].r,mid+1,r);
    }
    int find(int x){
        return lower_bound(num.begin(),num.end(),x)-num.begin()+1;
    }
    void insert(int &p,int q,int l,int r,int pos,int cnt){
        p=++idx,tr[p]=tr[q];
        tr[p].cnt+=1,tr[p].sum+=cnt;
        if(l==r){
            tr[p].d=cnt;
            return ;
        }
        int mid=l+r>>1;
        if(pos<=mid)
            insert(tr[p].l,tr[q].l,l,mid,pos,cnt);
        else
            insert(tr[p].r,tr[q].r,mid+1,r,pos,cnt);
    }
    ll query(int p,int q,int l,int r,int k){
        if(l==r){
            return tr[p].d*k;
        }
        int cnt=tr[tr[p].r].cnt-tr[tr[q].r].cnt;
        int mid=l+r>>1;
        if(k<=cnt){
            return query(tr[p].r,tr[q].r,mid+1,r,k);
        }
        else{
            return  tr[tr[p].r].sum-tr[tr[q].r].sum+query(tr[p].l,tr[q].l,l,mid,k-cnt);
        }
    }
    int main(){
        //ios::sync_with_stdio(false);
        int t;
        cin>>t;
        init();
        while(t--){
            cin>>n;
            int i;
            idx=0;
            num.clear();
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
                num.push_back(a[i]);
                rt[i]=0;
            }
            build(rt[0],1,n);
            sort(num.begin(),num.end());
            num.erase(unique(num.begin(),num.end()),num.end());
            for(i=1;i<=n;i++){
                insert(rt[i],rt[i-1],1,n,find(a[i]),a[i]);
            }
            int l,r,k;
            int q;
            cin>>q;
            while(q--){
                scanf("%d%d%d",&l,&r,&k);
                printf("%lld
    ",pre[(r-l+1)]+query(rt[r],rt[l-1],1,n,k));
            }
        }
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    PowerShell Arrays
    PowerShell Hashtable
    PowerShell Variables
    MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
    神奇的Timer
    神奇的Timer之lock篇
    利用lambda表达式正确关闭WCF连接
    Zendstutio设置
    一个服务器部署多个项目
    Magento模块配置文件
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13878916.html
Copyright © 2020-2023  润新知