• 【Luogu】P2154虔诚的墓主人(树状数组)


      题目链接

      这题就是考虑我们有这样一个情况

      然后我们试图很方便地求出第三行第二个和第三个常青树之间所有点上下常青树的组合。

      考虑使用树状数组,一开始把数组平放在最底下,然后往上推。

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    #include<cstring>
    #define maxn 200020
    #define maxd 12
    #define mod 2147483648
    using namespace std;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    struct Tree{
        long long x,y;
        bool operator <(const Tree a)const{
            if(x!=a.x)    return x<a.x;
            return y<a.y;
        }
    }q[maxn];
    
    long long s[maxn*2],cnt;
    long long c[maxn][maxd];
    
    long long tree[maxn*2];
    inline long long low(long long x){    return x&(-x);    }
    
    inline void add(long long pos,long long lim,long long num){
        while(pos<=lim){
            tree[pos]+=num;
            tree[pos]%=mod;
            pos+=low(pos);
        }
        return;
    }
    
    inline long long query(long long pos){
        long long ans=0;
        while(pos){
            ans+=tree[pos];
            ans%=mod;
            pos-=low(pos);
        }
        return ans;
    }
    
    
    long long up[maxn],down[maxn];
    long long lef[maxn],rig[maxn];
    
    int main(){
        long long m=read()+1,n=read()+1;
        long long e=read();
        for(long long i=1;i<=e;++i){
            q[i]=(Tree){read(),read()};
            swap(q[i].x,q[i].y);
            s[++cnt]=q[i].x;    s[++cnt]=q[i].y;
        }
        sort(s+1,s+cnt+1);
        long long size=unique(s+1,s+cnt+1)-s-1;
        for(long long i=1;i<=e;++i){
            q[i].x=lower_bound(s+1,s+size+1,q[i].x)-s;
            q[i].y=lower_bound(s+1,s+size+1,q[i].y)-s;
        }
        sort(q+1,q+e+1);
        for(long long i=1;i<=e;++i){
            up[q[i].y]++;
            rig[q[i].x]++;
        }
        long long d=read();
        for(long long i=0;i<=e;++i)    c[i][0]=1;
        for(long long i=1;i<=e;++i)
            for(long long j=1;j<=d;++j)    c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
        long long ans=0;
        for(long long i=1;i<=e;++i){
            if(q[i].x==q[i-1].x&&i!=1){
                //printf("i=%d
    xi=%d yi=%d
    %d %d %d %d
    ",i,q[i].x,q[i].y,lef[q[i].x],rig[q[i].x],query(q[i].y),query(q[i].y-q[i-1].y));
                ans+=c[lef[q[i].x]][d]*c[rig[q[i].x]][d]*(query(q[i].y-1)-query(q[i-1].y))%mod;
            }
            
            up[q[i].y]--;    down[q[i].y]++;
            lef[q[i].x]++;    rig[q[i].x]--;
            add(q[i].y,size,c[up[q[i].y]][d]*c[down[q[i].y]][d]-query(q[i].y)+query(q[i].y-1));
        }
        printf("%lld
    ",(ans%mod+mod)%mod);
        return 0;
    }
  • 相关阅读:
    SQLite
    Cryptology-3DES(Triple DES) -1981 American
    C#-Tips
    Tool-Wireshark
    Tool-Capture Packet
    Windbg-Debugging Tools for Windows网上搜集资料整理
    图像处理中的卷积操作和高斯核
    TypeError: Dense_net() takes 0 positional arguments but 1 was given
    查找数组中的重复元素
    数组和向量的二分查找
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/8952120.html
Copyright © 2020-2023  润新知