zoukankan      html  css  js  c++  java
  • bzoj1227

    离散化+树状数组+排列组合

    很久以前就看到过这道题,现在依然不会做。。。看完题解发现思路很简单,就是有点难写

    我们先将坐标离散化,x和y最大是w,然后我们就有了一个暴力做法, 枚举每块墓地,统计,因为墓地上下左右没东西的话就不可能有贡献,这些坐标自然就被离散化了,所以墓地最多有w*w块

    复杂度O(w*w),然后我们优化一下,发现不用枚举每个墓地,对于相邻两棵树,他们中间墓地左右的树的数量是相同的,这样的方案有C(l,k)*C(r,k),对于每个墓地,这样的虔诚度是C(l,k)*C(r,k)*C(up,k)*C(down,k),我们发现两棵树中间的墓地C(l,k)*C(r,k)是相同的,现在需要的就是统计sigma(C(up,k)*C(down,k)),我们可以用树状数组维护这个东西,先把墓地按行排序分类,然后每次对于每行枚举相邻的两棵树,计算之间的sigma,这样用树状数组统计,然后就是更新,有树的地方是需要更新的,就是把对应的y坐标离散化后的位置在树状数组里更新,减去原来的值,改成现在新的C(up,k)*C(down,k)

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 100010;
    const long long mod = 2147483648ll;
    int n, w, m, k;
    int up[N], down[N];
    long long c[N][12], BIT[N], ans;
    struct Tree {
        int x, y, ux, uy, left, right, up, down;
        bool friend operator < (Tree A, Tree B) 
        {
            return A.ux == B.ux ? A.uy < B.uy : A.ux < B.ux;
        }
    } tree[N];
    vector<Tree> line[N];
    inline int lowbit(int i) 
    {
        return i & (-i);
    }
    inline void update(int pos, int delta)
    {
        for(int i = pos; i <= w + 5; i += lowbit(i)) BIT[i] = (BIT[i] + delta) % mod;
    }
    inline long long query(int pos)
    {
        long long ret = 0;
        for(int i = pos; i; i -= lowbit(i)) ret = (ret + BIT[i]) % mod;
        return ret;
    }
    int main()
    {
        scanf("%d%d%d", &n, &m, &w);
        vector<int> vx, vy;
        for(int i = 1; i <= w; ++i) 
        {
            scanf("%d%d", &tree[i].x, &tree[i].y);
            vx.push_back(tree[i].x);
            vy.push_back(tree[i].y);
        }
        scanf("%d", &k);
        c[0][0] = 1;
        for(int i = 1; i <= w; ++i)
        {
            c[i][0] = 1;
            for(int j = 1; j <= min(k, i); ++j) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
        }
        sort(vx.begin(), vx.end());
        sort(vy.begin(), vy.end());
        vx.erase(unique(vx.begin(), vx.end()), vx.end());
        vy.erase(unique(vy.begin(), vy.end()), vy.end());   
        for(int i = 1; i <= w; ++i)
        {
            tree[i].ux = lower_bound(vx.begin(), vx.end(), tree[i].x) - vx.begin() + 1;
            tree[i].uy = lower_bound(vy.begin(), vy.end(), tree[i].y) - vy.begin() + 1; 
    //      printf("ux=%d uy=%d
    ", tree[i].ux, tree[i].uy);
        }
        sort(tree + 1, tree + w + 1);
        for(int i = 1; i <= w; ++i)
        {
            ++up[tree[i].uy];
            tree[i].up = up[tree[i].uy];        
        }
        for(int i = w; i; --i) 
        {
            tree[i].down = down[tree[i].uy];
            ++down[tree[i].uy]; 
        }
        for(int i = 1; i <= w; ++i) line[tree[i].ux].push_back(tree[i]);
        for(int i = 1; i <= vx.size(); ++i) 
        {
            sort(line[i].begin(), line[i].end());   
            for(int j = 0; j < line[i].size(); ++j)
            {
                Tree &tmp = line[i][j];
                tmp.left = j + 1;
                tmp.right = line[i].size() - j; 
            }
        }
        for(int i = 1; i <= vx.size(); ++i)
        {
            for(int j = 1; j < line[i].size(); ++j)
            {
                Tree tmp_l = line[i][j - 1], tmp_r = line[i][j];
                long long comb_left = c[tmp_l.left][k], comb_right = c[tmp_r.right][k], sigma = query(tmp_r.uy - 1) - query(tmp_l.uy);
                ans = (ans + comb_left % mod * comb_right % mod * sigma % mod) % mod;       
            }
            for(int j = 0; j < line[i].size(); ++j)
            {
                Tree tmp = line[i][j];
                update(tmp.uy, c[tmp.up][k] % mod * c[tmp.down][k] % mod - query(tmp.uy) + query(tmp.uy - 1));
            }
        }
        printf("%lld
    ", (ans % mod + mod) % mod);
        return 0;
    }
    View Code
  • 相关阅读:
    总结的git操作命令小抄集
    两种方式实现压缩文件或文件夹
    eclipse 中执行 main 函数如何添加参数
    alert()、confirm()和prompt()的区别与用法
    阿里某安全工程师写的明星代码
    在 Linux 环境下报错 java.lang.reflect.InvocationTargetException
    MyBatis学习-SQL 符号篇
    初识IP基础分类、CIDR
    Snort
    Dshell----开源攻击分析框架
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7337355.html
Copyright © 2011-2022 走看看