hdu5057 分块法
2015-08-07 23:59
281 查看
题意:n个数,n<=100000,单点修改,区间询问一段内第D位为P的数的个数。内存卡的很死,树状数组会超内存。分块大法好。
每一块为256个数字,(i>>8)即为i所在的块。
每一块为256个数字,(i>>8)即为i所在的块。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #define ll long long using namespace std; const int maxn=100005; int n,m; int digit[maxn][10]; int block[400][10][10]; int X,Y,L,R,D,P; int main() { int x; char str[10]; int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(block,0,sizeof(block)); for(int i=1;i<=n;i++) { scanf("%d",&x); int b=(i>>8); for(int j=1;j<=10;j++) { digit[i][j]=x%10; block[b][j][x%10]++; x/=10; } } for(int i=0;i<m;i++) { scanf("%s",str); if(str[0]=='S') { scanf("%d%d",&X,&Y); int b=(X>>8); for(int j=1;j<=10;j++) { block[b][j][digit[X][j]]--; digit[X][j]=Y%10; block[b][j][Y%10]++; Y/=10; } } else { scanf("%d%d%d%d",&L,&R,&D,&P); int bl=((L-1)>>8)+1,br=((R+1)>>8)-1; int ans=0; if(bl<=br) { for(int i=bl;i<=br;i++) ans+=block[i][D][P]; for(int i=L;i<(bl<<8);i++) ans+=(digit[i][D]==P); for(int i=((br+1)<<8);i<=R;i++) ans+=(digit[i][D]==P); } else { for(int i=L;i<=R;i++) { ans+=(digit[i][D]==P); } } printf("%d\n",ans); } } } return 0; }
相关文章推荐
- hdu 1171 Big Event in HDU
- 学习方法的思考
- 删除数据库日志
- Leetcode46 Permutations
- 使用VMM服务器构建 Hyper-V主机(4)
- 八条千金不卖的人生感悟
- 【JAVA】接口(一)
- tarjan算法之 强连通分量
- 使用VMM服务器构建 Hyper-V 主机(3)
- USB组合设备 Interface Association Descriptor (IAD)
- 生成器 种子
- 使用VMM服务器构建 Hyper-V主机(2)
- Codeforces Round #312 (Div. 2) B. Amr and The Large Array
- UVA 1218 (树形DP)
- 利用HTML5 Canvas和Javascript实现的蚁群算法求解TSP问题演示
- 使用VMM服务器构建Hyper-V主机(1)
- MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost'
- poj2752
- 六间房 繁星 酷我 来疯 秀吧 新浪秀 直播播放器 Live 1.2
- const、volatile、mutable的用法