[BOI2007]摩基亚
题目:洛谷P4390、BZOJ1176。
题目大意:
给你一个W×W的矩阵,初始每个数都为S。现在有若干操作:
1. 给某个格子加上一个值;
2. 询问某个子矩阵的值的和;
3. 结束询问
解题思路:
CDQ分治。
离线操作,把询问拆成4个矩阵(二维前缀和)。
对x轴排序,分治询问,用左区间的修改来更新右区间的询问。由于x已被排序,我们直接用树状数组维护y的前缀和即可。
也可以边CDQ边归并排序。
时间复杂度O(nlog2n)。
C++ Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #include<cstdio> #include<algorithm> #include<cctype> #define LoveLive long long #define M 2000005 int S,W,cnt=0; LoveLive bit[M]; inline int readint(){ int c= getchar (),d=0,f=0; for (;! isdigit (c);c= getchar ())f=c== '-' ; for (; isdigit (c);c= getchar ()) d=(d<<3)+(d<<1)+(c^ '0' ); return f?-d:d; } struct Qs{ int type,x,y,id;LoveLive num; //type 0: modify; type 1: query. inline bool operator<( const Qs&rhs) const { return id<rhs.id;} }q[200020],t[200020]; inline void add( int x,LoveLive y){ for ( int i=x;i<M;i+=i&-i)bit[i]+=y;} inline LoveLive ask( int x){LoveLive ans=0; for ( int i=x;i;i-=i&-i)ans+=bit[i]; return ans;} inline void clear( int x){ for ( int i=x;i<M;i+=i&-i)bit[i]=0;} void cdq( int l, int r){ if (l<r){ int mid=l+r>>1; cdq(l,mid),cdq(mid+1,r); int a=l,b=mid+1,c=l; while (a<=mid&&b<=r){ if (q[a].x<=q[b].x){ if (!q[a].type)add(q[a].y,q[a].num); t[c++]=q[a++]; } else { if (q[b].type)q[b].num+=ask(q[b].y); t[c++]=q[b++]; } } while (a<=mid){ if (!q[a].type)add(q[a].y,q[a].num); t[c++]=q[a++]; } while (b<=r){ if (q[b].type)q[b].num+=ask(q[b].y); t[c++]=q[b++]; } for ( int i=l;i<=mid;++i) if (!q[i].type)clear(q[i].y); for ( int i=l;i<=r;++i)q[i]=t[i]; } } int main(){ S=readint(),W=readint(); for ( int opt=readint();opt^3;opt=readint()){ if (opt==1){ int x=readint(),y=readint(),p=readint(); ++cnt; q[cnt]=(Qs){0,x,y,cnt,p}; } else { int x1=readint(),y1=readint(),x2=readint(),y2=readint(); ++cnt;q[cnt]=(Qs){1,x1-1,y1-1,cnt,0}; ++cnt;q[cnt]=(Qs){1,x1-1,y2,cnt,0}; ++cnt;q[cnt]=(Qs){1,x2,y1-1,cnt,0}; ++cnt;q[cnt]=(Qs){1,x2,y2,cnt,0}; } } cdq(1,cnt); std::sort(q+1,q+cnt+1); for ( int i=1;i<=cnt;++i) if (q[i].type){ printf ( "%d\n" , int (q[i+3].num-q[i+2].num-q[i+1].num+q[i].num+1ll*S*(q[i+3].y-q[i].y)*(q[i+3].x-q[i].x)));i+=3; } return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
· 本地部署 DeepSeek:小白也能轻松搞定!
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 如何基于DeepSeek开展AI项目
2017-07-10 [HDU2874]Connections between cities