zoukankan      html  css  js  c++  java
  • 2019icpc南京网络赛 A 主席树

    题意

    给一个(n imes n)的螺旋矩阵,给出其中的(m)个点的值分别为各个点上数字的数位之和,给出(q)个询问,每次询问从((x1,y1))((x2,y2))的子矩阵的和。

    分析

    用官方题解的方法(O(1))推出点((x,y))上的值,将这(m)个点按(x)排序后依次按(y)建主席树,查询时找到对应的(x1)(x2)的历史版本,查询(y1)(y2)的权值和就行了,((query(y1,y2,1,n,rt[l],rt[r])));

    Code

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define pb push_back
    #define ll long long
    using namespace std;
    const int inf=1e9;
    const int mod=1e9+7;
    const int maxn=1e6+10;
    int T,n,m,q;
    ll tr[maxn*30];
    int ls[maxn*30],rs[maxn*30],rt[maxn],tot;
    struct ppo{
        int x,y;
        ll c;
        bool operator<(const ppo &r)const{
            return x<r.x;
        }
    }a[maxn];
    ll fun(ll i,ll j,ll n){
        ll ans;
        j=n-j+1;i=n-i+1;
        ll minn=min(i,min(j,min(n-i+1,n-j+1)));
        if(i<=j) ans=minn*(4*(n-1)-4*minn)+10*minn-4*n-3+i+j;
        else ans=minn*(4*n-4*minn)+2*minn+1-i-j; 
        ll sum = 0;
        while(ans){
            sum+=ans%10;
            ans/=10;
        }
        return sum;
    }
    void bd(int l,int r,int &p){
        tr[++tot]=tr[p],ls[tot]=ls[p],rs[tot]=rs[p],p=tot;
        if(l==r) return;
        int mid=l+r>>1;
        bd(l,mid,ls[p]);bd(mid+1,r,rs[p]);
    }
    void up(int k,int l,int r,int x,int &p){
        tr[++tot]=tr[p]+x,ls[tot]=ls[p],rs[tot]=rs[p],p=tot;
        if(l==r) return;
        int mid=l+r>>1;
        if(k<=mid) up(k,l,mid,x,ls[p]);
        else up(k,mid+1,r,x,rs[p]);
    }
    ll qy(int dl,int dr,int l,int r,int a,int b){
        if(l>=dl&&r<=dr){
            return tr[b]-tr[a];
        }int mid=l+r>>1;ll ret=0;
        if(dl<=mid) ret+=qy(dl,dr,l,mid,ls[a],ls[b]);
        if(dr>mid) ret+=qy(dl,dr,mid+1,r,rs[a],rs[b]);
        return ret;
    }
    int main(){
        //ios::sync_with_stdio(false);
        //freopen("in","r",stdin);
        scanf("%d",&T);
        while(T--){
            tot=0;
            scanf("%d%d%d",&n,&m,&q);
            for(int i=1,x,y;i<=m;i++){
                scanf("%d%d",&x,&y);
                a[i]=ppo{x,y,fun(x,y,n)};
            }
            sort(a+1,a+m+1);
            bd(1,n,rt[0]);
            for(int i=1;i<=m;i++){
                rt[i]=rt[i-1];
                up(a[i].y,1,n,a[i].c,rt[i]);
            }
            while(q--){
                int x1,y1,x2,y2;
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                int l=lower_bound(a+1,a+m+1,ppo{x1,0,0})-a-1;
                int r=upper_bound(a+1,a+m+1,ppo{x2,0,0})-a-1;
                printf("%lld
    ",qy(y1,y2,1,n,rt[l],rt[r]));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    温故而知新--JavaScript书摘(二)
    WebSocket 浅析
    温故而知新--JavaScript书摘(一)
    HTTP2.0 简明笔记
    XHR简介
    HTTP 1.1学习笔记
    选择一个 HTTP 状态码不再是一件难事 – Racksburg《转载》
    Buffer学习笔记.
    浏览器的userAgent归纳
    Ngnix日志分析
  • 原文地址:https://www.cnblogs.com/xyq0220/p/11444041.html
Copyright © 2011-2022 走看看