题目链接

分析 :

最简单的想法当然就是去模拟

直接对每个施肥料的操作进行模拟、然后计算贡献

但是这显然会超时、这题需要换一个思维

对于一个土地(也就是二维平面上的一个点)的种类是 T'

如果它被操作了 K1 次、那么如果我能知道所有用 T' 施肥的操作

对这块土地施肥的次数 K2、那么当 K1 == K2 的时候、这片土地就不会 Die

而当 K1 != K2 的时候、则这块土地就会 Die 、换句话说就是答案要加一

计算每个土地被操作的总次数

要知道每个土地被操作了多少次、可以利用二维前缀和的方式来计算贡献

假设操作矩形的左上角和右下角分别为 (x1, y1) 、(x2, y2)

那么可以用二维数组模拟这个矩形的四个顶点分别做加减操作

具体的就是 arr[x1][y1]++、arr[x1][y2+1]--、arr[x2+1][y1]--、arr[x2][y2]++

然后 N*M 地去遍历整个土地、利用这条式子 arr[i][j] += arr[i-1][j] + arr[i][j-1] - arr[i-1][j-1]

最后 arr 这个二维数组中所有的数字表示的即为某一块土地被操作的总次数

计算被用于操作的肥料对其施肥的土地操作的总次数

如果仔细思考一下便会发现这个是一个很经典的二维偏序问题

如果你解决过类似 CDQ 分治的题目、那么这个便会很容易理解

对于每个种类的肥料、其可能被用于若干次施肥操作

施肥操作是一个矩形、可以将矩形操作分解成四个点的加减操作

也就是将一个操作变成四个操作、如果你熟悉 CDQ 分治、那么这个会好理解

可以发现对于每一个点、在二维平面上只有其左上角的操作点对它有影响

所以每次处理都将所有操作对于 X 轴先进行排序、然后利用树状数组维护 Y 轴

还有一开始的原矩形元素也应该被视作操作、保存到分治数组里面去、用于问询

可能很乱,看代码就清楚了

(最好是你先去熟悉偏序问题和CDQ分治、因为代码的很多细节都是套路操作、不赘述了)

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long#define scl(i) scanf("%lld", &i)
#define scll(i, j) scanf("%lld %lld", &i, &j)
#define sclll(i, j, k) scanf("%lld %lld %lld", &i, &j, &k)
#define scllll(i, j, k, l) scanf("%lld %lld %lld %lld", &i, &j, &k, &l)#define scs(i) scanf("%s", i)
#define sci(i) scanf("%d", &i)
#define scd(i) scanf("%lf", &i)
#define scIl(i) scanf("%I64d", &i)
#define scii(i, j) scanf("%d %d", &i, &j)
#define scdd(i, j) scanf("%lf %lf", &i, &j)
#define scIll(i, j) scanf("%I64d %I64d", &i, &j)
#define sciii(i, j, k) scanf("%d %d %d", &i, &j, &k)
#define scddd(i, j, k) scanf("%lf %lf %lf", &i, &j, &k)
#define scIlll(i, j, k) scanf("%I64d %I64d %I64d", &i, &j, &k)
#define sciiii(i, j, k, l) scanf("%d %d %d %d", &i, &j, &k, &l)
#define scdddd(i, j, k, l) scanf("%lf %lf %lf %lf", &i, &j, &k, &l)
#define scIllll(i, j, k, l) scanf("%I64d %I64d %I64d %I64d", &i, &j, &k, &l)#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define lowbit(i) (i & (-i))
#define mem(i, j) memset(i, j, sizeof(i))#define fir first
#define sec second
#define VI vector<int>
#define ins(i) insert(i)
#define pb(i) push_back(i)
#define pii pair<int, int>
#define VL vector<long long>
#define mk(i, j) make_pair(i, j)
#define all(i) i.begin(), i.end()
#define pll pair<long long, long long>#define _TIME 0
#define _INPUT 0
#define _OUTPUT 0
clock_t START, END;
void __stTIME();
void __enTIME();
void __IOPUT();
using namespace std;
const int maxn = 1e6 + 100;struct ARR{int r, c, op;ARR(){};ARR(int _r, int _c, int _o):r(_r), c(_c), op(_o){};bool operator < (const ARR & rhs) const{if(r == rhs.r && c == rhs.c) return abs(op) > abs(rhs.op);if(r == rhs.r) return c < rhs.c;return r < rhs.r;}
}; vector<ARR> arr[maxn];int n, m, T;
int Cnt[maxn<<1];
int Bit[maxn];inline void BitAdd(int i, int val)
{while(i <= m){Bit[i] += val;i += (i & (-i));}
}int BitSum(int i)
{if(i == 0) return 0;int ret = 0;while(i > 0){ret += Bit[i];i -= (i & (-i));}return ret;
}void BitClean(int i)
{while(i <= m){Bit[i] = 0;i += (i & (-i));}
}int idx(int r, int c)
{ return r * m + c; }int main(void){__stTIME();__IOPUT();sciii(n, m, T);for(int i=1; i<=n; i++)for(int j=1; j<=m; j++){int tmp; sci(tmp);arr[tmp].pb(ARR(i, j, 0));}for(int i=0; i<T; i++){int x1, y1, x2, y2, k;sciiii(x1, y1, x2, y2); sci(k);arr[k].pb(ARR(x1, y1, 1));arr[k].pb(ARR(x1, y2+1, -1));arr[k].pb(ARR(x2+1, y1, -1));arr[k].pb(ARR(x2+1, y2+1, 1));Cnt[idx(x1, y1)]++;Cnt[idx(x1, y2+1)]--;Cnt[idx(x2+1, y1)]--;Cnt[idx(x2+1, y2+1)]++;}for(int i=1; i<=n; i++)for(int j=1; j<=m; j++)Cnt[idx(i, j)] += Cnt[idx(i-1, j)] +Cnt[idx(i, j-1)] -Cnt[idx(i-1, j-1)];//    for(int i=1; i<=n; i++,puts(""))
//        for(int j=1; j<=m; j++)
//            printf("%d ", Cnt[idx(i, j)]);int ans = 0;for(int i=1; i<=n*m; i++){sort(all(arr[i]));//printf("----- %d ------\n", i);for(int j=0; j<(int)arr[i].size(); j++){//printf("$$=> %d %d %d\n", arr[i][j].r, arr[i][j].c, arr[i][j].op);if(arr[i][j].op == 0){if(Cnt[idx(arr[i][j].r, arr[i][j].c)] != BitSum(arr[i][j].c))ans++;}else BitAdd(arr[i][j].c, arr[i][j].op);}for(int j=0; j<(int)arr[i].size(); j++){if(arr[i][j].op != 0)BitClean(arr[i][j].c);}}printf("%d\n", ans);__enTIME();return 0;}void __stTIME()
{#if _TIMESTART = clock();#endif
}void __enTIME()
{#if _TIMEEND = clock();cerr<<"execute time = "<<(double)(END-START)/CLOCKS_PER_SEC<<endl;#endif
}void __IOPUT()
{#if _INPUTfreopen("in.txt", "r", stdin);#endif#if _OUTPUTfreopen("out.txt", "w", stdout);#endif
}

View Code

转载于:https://www.cnblogs.com/LiHior/p/9457392.html

Nowcoder farm ( 树状数组、二维前缀和、二维偏序 )相关推荐

  1. P4062 [Code+#1]Yazid 的新生舞会(区间绝对众数+分治/树状数组维护高维前缀和)

    P4062 [Code+#1]Yazid 的新生舞会 杭电多校懂得都懂 Code1 分治 比较喜欢分治的做法,非常好写.skylee大佬题解 首先对于任何一个区间来说,由于两个端点不确定性非常难以一次 ...

  2. 高级数据结构1—初识树状数组—快速求得前缀和和修改某一元素值

    - 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~ 本人Gitee账号:路由器,欢迎关注获取博客内容源码.   树状数组和其他的高级数据结构不同,它非常的好写,同 ...

  3. 树状数组 ---- 树状数组+动态维护前缀中位数 D. Omkar and Medians

    题目大意: 解题思路: 首先我们看他们的定义: bib_ibi​是a1,a2,a3,....,ai,ai+1,.......a2i−1a_1,a_2,a_3,....,a_i,a_{i+1},.... ...

  4. szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】

    树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...

  5. 数据结构一【树状数组】普通、二维、离线树状数组的(单点修改,单点查询,区间修改,区间查询)模板及应用例题总结

    文章目录 树状数组 lowbit 线段树与树状数组 单点修改 区间查询 区间修改 区间求和 二维树状数组 离线树状数组 例题 POJ:stars MooFest [SDOI2009]HH的项链 Tur ...

  6. 数据结构:树状数组:姐来展示下什么叫高端前缀和

    树状数组:花式前缀和 一.位运算:lowbit() 二.树状数组介绍 三.离散化 四.实战题目: 五.树状数组变式:支持区间查找的HashMap 我们知道前缀和是十分高效的,可以以O(1)的速度求出任 ...

  7. C - The Battle of Chibi (dp加树状数组前缀和优化)

    曹操组成大军,要攻打整个华南.于舟很担心.他认为击败曹操的唯一方法是在曹操的军队中配备一个间谍.但曹操的将领和士兵都是忠诚的,不可能说服他们中的任何一个人背叛曹操. 所以余州只剩下一条路,派人假投降曹 ...

  8. 【HDU - 6447】YJJ's Salesman(降维dp,树状数组优化dp)

    题干: YJJ is a salesman who has traveled through western country. YJJ is always on journey. Either is ...

  9. 树状数组 讲解和题目集

    树状数组 树状数组作为一种实现简单.应用较广的高级数据结构,在OI界的地位越来越重要,下面我来简单介绍一下树状数组和它的简单应用. 一.树状数组简介 树状数组:顾名思义,是一种数组,其中包含了树的思想 ...

最新文章

  1. 经典SQL语句大全(提升篇)
  2. 在Nginx上配置多个站点
  3. 已知三角形三边长怎么求面积_已知三角形三边求面积的公式——海伦公式
  4. 传递子类 java_Java,将主类传递给子类,错误的编码风格?
  5. localStorage.getItem 往浏览器里面储存数据到本地localStorage
  6. 计算机专硕专业课单科分数线,计算机考研|这两所自划线,单科没过线也能复试?...
  7. JS代码优化工具Prepack
  8. 阿里的Json解析包FastJson使用
  9. 2016012013 王雪 散列函数的应用及其安全性
  10. 基于各系统平台(RedHat Linux、SUSE Linux、CentOS、SUN Solaris10) FTP服务的配
  11. 电脑公司ghost win8 64位家庭克隆版v2020.05
  12. 用户画像及其应用案例分享
  13. hive教程:第一次使用sql
  14. 不错的离线IP地址定位库
  15. 【智能路由器】openwrt添加服务项
  16. hash与history 以及区别
  17. 去哪儿APP 算法初探窥镜
  18. python基础入门1
  19. 天地孤影任我行(东邪西毒电影原声曲)铃声 天地孤影任我行(...
  20. 计算机主机有自带的声音吗,为什么我的电脑没有声音|电脑没有声音怎么办|电脑没有声音怎么回事 - 为什么我的电脑没有声音 - 安全专题...

热门文章

  1. C++中的继承(派生)的一些误区
  2. 【网络信息安全】Web 安全
  3. CentOS6安装netcat 瑞士军刀【附带下载资源链接】
  4. Linux下服务器搭建(5)——CentOS下Redis的安装
  5. CTA策略05_AtrRsiStrategy
  6. 比Excel还简单,跳槽数据分析岗必会的工具
  7. 2019年企业数据生产力调研报告,90%的人都没看过
  8. 验证方式二 html标签验证码,Django标签、转义及验证码生成
  9. python源_python更换国内源
  10. protobuf java 自动反射_protobuf在java应用中通过反射动态创建对象