P8470 [Aya Round 1 E] 乙(two)

题目链接

1|0Solution

本题是动态询问我们图形的侧面积,由于数据较大,肯定不能每一次暴力查找。所以我们考虑每一次的贡献。

假设说我们每一次都没有跟别的方块有冲突,那么每一次的贡献就是 z×4,然后我们要考虑重合的部分。

设放的当前方块原来有 now 个,现在放上去 z 个,开一个 map,看它前后左右是否有方块,如果有,设它的高度为 h,若 hnow,则不会有冲突;若 h>now,则出现冲突的高度为 min(z,hnow),并且它会影响两个面,所以冲突的面积为 2×min(z,hnow)

所以我们每次查询先加上 z×4,再减去冲突的面积就是答案。

注意由于最大的答案可能到 1.2×1019,要开 unsigned long long。

2|0Code

#include<bits/stdc++.h> #define int unsigned long long using namespace std; void read(int &x) { char ch=getchar(); int r=0,w=1; while(!isdigit(ch))w=ch=='-'?-1:1,ch=getchar(); while(isdigit(ch))r=(r<<3)+(r<<1)+(ch^48),ch=getchar(); x=r*w; } map<pair<int,int>,int>mp; void write(int x) { char ch[20]; int len=0; if(x<0)putchar('-'),x=-x; while(x) { ch[len++]=(x%10)^48; x/=10; } if(len==0)printf("0"); while(len--)putchar(ch[len]); puts(""); } main() { int T,sum=0; read(T); while(T--) { int x,y,z; read(x);read(y);read(z); int now=mp[make_pair(x,y)]; if(mp[make_pair(x+1,y)]) { int k=mp[make_pair(x+1,y)]; if(k>now)sum-=min(k-now,z)*2; } if(mp[make_pair(x-1,y)]&&x>0) { int k=mp[make_pair(x-1,y)]; if(k>now)sum-=min(k-now,z)*2; } if(mp[make_pair(x,y+1)]) { int k=mp[make_pair(x,y+1)]; if(k>now)sum-=min(k-now,z)*2; } if(mp[make_pair(x,y-1)]&&y>0) { int k=mp[make_pair(x,y-1)]; if(k>now)sum-=min(k-now,z)*2; } sum+=z*4; mp[make_pair(x,y)]+=z; write(sum); } return 0; }

__EOF__

本文作者JMartin
本文链接https://www.cnblogs.com/LAK666/p/16564761.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Epoch_L  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示