博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
0x03 前缀和与差分
阅读量:5338 次
发布时间:2019-06-15

本文共 2627 字,大约阅读时间需要 8 分钟。

前缀和

计算二位前缀和,再利用容斥原理计算出答案即可。

1 #include 
2 #include
3 #include
4 #include
5 using namespace std; 6 const int maxn=5000+10; 7 int n, r, sum[maxn][maxn]; 8 9 int main() {10 scanf("%d%d", &n, &r);11 int x, y, v, maxx=0, maxy=0;12 maxx=maxy=r;13 for (int i=1; i<=n; ++i) {14 scanf("%d%d%d", &x, &y, &v);15 ++x; ++y;16 maxx=max(maxx, x); maxy=max(maxy, y);17 sum[x][y]=v;18 }19 for (int i=1; i<=maxx; ++i) {20 for (int j=1; j<=maxy; ++j) {21 sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];22 }23 }24 //枚举面积为r的正方形25 int ans=0;26 for (int i=r; i<=maxx; ++i) {27 for (int j=r; j<=maxy; ++j) {28 ans=max(ans, sum[i][j]-sum[i-r][j]-sum[i][j-r]+sum[i-r][j-r]);29 }30 } 31 printf("%d\n", ans);32 return 0;33 }

差分

求出序列a的差分序列b,令bn+1=0,目标是将把b2,b3...bn变为全0。

把序列a区间[l,r]加d,其差分序列的变化为Bl加d,Br+1减d。

从b1,b2...bn中任选两个数的方法可以分为4类:

1.选bi和bj

2.选b1和bj

3.选bi和bn+1

4.选b1和bn+1,这种选法没有意义

设整数总和为p,负数总和为q,首先以正负数匹配的方式尽量选择操作1,可执行min(p,q)次。

剩余|p-q|个未配对,执行操作2和操作3,共需|p-q|次。

所以最少操作次数为min(p,q)+|p-q|=max(p,q)次,根据操作2,3的选择情况,能产生|p-q|+1种b1的值,即序列a可能有|p-q|+1种。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 using namespace std; 7 const int maxn=100000+10; 8 long long n, a[maxn], s[maxn], p=0, q=0; 9 10 int main() {11 scanf("%lld", &n);12 for (int i=1; i<=n; ++i)13 scanf("%lld", &a[i]);14 s[1]=a[1]; s[n+1]=0;15 for (int i=2; i<=n; ++i) {16 s[i]=a[i]-a[i-1];17 }18 for (int i=2; i<=n; ++i) {19 if (s[i]>0) p+=s[i];20 else if (s[i]<0) q-=s[i];21 }22 printf("%lld\n%lld\n", max(p,q), abs(p-q)+1);23 return 0;24 }

若有一条关系指明Ai和Bi可以互相看见,就将他们数组中Ai+1到Bi-1的数减去1,最终得到所有牛与最高的牛p的相对身高关系。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 using namespace std; 8 const int maxn=100000+10; 9 int n, p, h, m, c[maxn], d[maxn];10 map
, bool> ext;11 12 int main() {13 scanf("%d%d%d%d", &n, &p, &h, &m);14 int a, b;15 for (int i=1; i<=m; ++i) {16 scanf("%d%d", &a, &b);17 if (a>b) swap(a,b);18 if (ext[make_pair(a,b)]) continue;19 d[a+1]--, d[b]++;20 ext[make_pair(a,b)]=true;21 }22 for (int i=1; i<=n; ++i) {23 c[i]=c[i-1]+d[i];24 printf("%d\n", h+c[i]);25 }26 return 0;27 }

 

转载于:https://www.cnblogs.com/kkkstra/p/11104629.html

你可能感兴趣的文章
SparkStreaming 源码分析
查看>>
【算法】—— 随机音乐的播放算法
查看>>
mysql asyn 示例
查看>>
DataGrid 点击 获取 行 ID
查看>>
git 使用
查看>>
边框圆角方法
查看>>
asp.net WebApi自定义权限验证消息返回
查看>>
php中eval函数的危害与正确禁用方法
查看>>
20172315 2017-2018-2 《程序设计与数据结构》第十一周学习总结
查看>>
MySQL添加、修改、撤销用户数据库操作权限的一些记录
查看>>
C#中List和数组之间转换的方法
查看>>
屏幕分辨率过高导致软件界面显示过小影响使用
查看>>
ViewBag & ViewData
查看>>
关于谷歌浏览器Chrome正在处理请求的问题解决
查看>>
Git核心技术:在Ubuntu下部署Gitolite服务端
查看>>
平面波展开法总结
查看>>
建造者模式
查看>>
ArraySort--冒泡排序、选择排序、插入排序工具类demo
查看>>
composer 安装laravel
查看>>
8-EasyNetQ之Send & Receive
查看>>