zoukankan      html  css  js  c++  java
  • Light OJ 1343

    题目

    link
    求偶数子序列这里写图片描述
    满足 这里写图片描述
    的个数。

    分析

    首先, 我们先把每一对a[i] + a[j]存起来, 这样就可以把题目的偶数个条件无视了。
    设 T[i,j] = a[i] + a[j]; 因为我们是要求序列个数, 所以对于 [i,j]区间, 我们
    要找出 [i,j] 内有多少对满足 T[x,y] < T[i,j] 的。
    把 (i,j)想成坐标系的点, 那么上面求的就是 平面矩形 {[i,i],[j,j]} 中有多少点。
    利用前缀和 和矩形相减就可以快速得出了。所以用二维的树状数组维护就有了。
    

    Code

    取余是一个特殊值, 可以直接用unsigned更加简便。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    const LL MOD = 1LL<<32;
    const int maxn = 500 + 31;
    
    struct Point {
        int x, y;
        LL sum;
    
        Point(int _x, int _y, LL _s):
            x(_x),y(_y),sum(_s){}
    
        bool operator < (const Point a) const {
            if(sum == a.sum) {
                return x == a.x ? y < a.y : x < a.x;
            } else return sum < a.sum;
        }
    };
    
    vector<Point> Tmp;
    LL Num[maxn][maxn];
    LL A[maxn], B[maxn];
    
    ///BIT
    int lowbit(int x) { return x&(-x); }
    LL Sum(int x, int y) {
        LL ret = 0;
        int xx = x;
        while(xx > 0) {
            int yy = y;
            while(yy > 0)
            {
                ret = (ret + Num[xx][yy]) % MOD;
                yy -= lowbit(yy);
            }
            xx -= lowbit(xx);
        }
        return ret;
    }
    void Add(int x, int y, LL Val) {
        int xx = x;
        while(xx < maxn)
        {
            int yy = y;
            while(yy < maxn)
            {
                Num[xx][yy] = (Num[xx][yy] + Val) % MOD;
                yy += lowbit(yy);
            }
            xx += lowbit(xx);
        }
    }
    
    int main() {
        //cout  << MOD <<endl;
        int t, n;
        scanf("%d",&t);
        for(int kase = 1; kase <= t; ++kase)
        {
            Tmp.clear();
            memset(Num,0,sizeof(Num));
            scanf("%d",&n);
            for(int i = 0; i < n; ++i)
                scanf("%lld",A+i);
            for(int i = 0; i < n; ++i)
            for(int j = i+1; j < n; ++j)
            {
                Tmp.push_back(Point(i+1,j+1,(A[i]+A[j])%MOD));
            }
            sort(Tmp.begin(), Tmp.end());
            LL Ans = 0;
            for(int i = 0; i < Tmp.size(); ++i)
            {
                Point t = Tmp[i];
                LL ss = (Sum(t.y-1,t.y-1) - Sum(t.x,t.y-1) + MOD) % MOD;
                ss = (ss  - Sum(t.y-1,t.x) + Sum(t.x,t.x) + MOD) % MOD;
                ss = (ss+1) % MOD;
                Ans = (Ans + ss) % MOD;
                Add(t.x,t.y,ss);
            }
            //Ans %= MOD;
            printf("Case %d: %lld
    ",kase, Ans);
        }
        return 0;
    }
    
  • 相关阅读:
    深入理解Java虚拟机之.class文件的数据结构一
    计算机操作系统之文件管理二
    计算机操作系统之文件管理一
    深入理解Java虚拟机之垃圾收集二
    深入理解Java虚拟机之垃圾收集一
    深入理解Java虚拟机之内存管理
    iscsi remote boot
    Autoconfigure enviroment via Python script
    How to set up a PXE server with REHL 7 OS
    jQuery如何获取动态添加的元素
  • 原文地址:https://www.cnblogs.com/aoxuets/p/5506826.html
Copyright © 2011-2022 走看看