标签:des style http color io os ar java strong
1 5 7 10 11 12 13 14 Q 1 5 2 1 Q 1 5 1 0 Q 1 5 1 1 Q 1 5 3 0 Q 1 5 3 1 S 1 100 Q 1 5 3 1
5 1 1 5 0 1
这道题有三种版本的 题解,本来题目不难,就是限制空间:1.分块算法解决,2.离线树状数组,3.卡空间的树状数组
这里先介绍第一种算法:
学习了一下分块算法,其实还蛮简单的,就是将n组元素分成m组,每组合并成一块,查询时,只要看元素在那几块,相加就行了。
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; struct Block { int nt[10][10]; }block[400]; int num[100010]; int cal(int d) { int ans=1; for(int i=1;i<=d;i++) { ans*=10; } return ans; } int init(int n) { int s=(int)sqrt((double)n),t=0; int m=n/s+1; memset(block,0,sizeof(block)); for(int i=1;i<=n;i++) { scanf("%d",&num[i]); s=i/m;t=num[i]; for(int j=0;j<=9;j++) { block[s].nt[j][t%10]++; t/=10; } } return m; } void work(int k,int n,int m) { char s[2]; int l,r,d,p,tl,tr,td,tp,ans=0; while(m--) { scanf("%s",s); if(s[0]=='S') { scanf("%d%d",&d,&p); td=d;td/=k; for(int j=0;j<=9;j++) { block[td].nt[j][num[d]%10]--; num[d]/=10; } num[d]=p;tp=p; for(int j=0;j<=9;j++) { block[td].nt[j][tp%10]++; tp/=10; } } else { ans=0; scanf("%d%d%d%d",&l,&r,&d,&p); tl=l;tl/=k;tr=r;tr/=k;d--; td=cal(d); if(tl==tr) { for(int i=l;i<=r;i++) if(num[i]/td%10==p) { ans++; } printf("%d\n",ans); } else { for(int i=tl+1;i<tr;i++) { ans+=block[i].nt[d][p]; } tl=(tl+1)*k; for(int i=l;i<tl;i++) if(num[i]/td%10==p) { ans++; } tr*=k; for(int i=tr;i<=r;i++) if(num[i]/td%10==p) { ans++; } printf("%d\n",ans); } //cout<<"??"<<endl; } } } int main() { int cas,m,n; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); int k=init(n); work(k,n,m); } return 0; }
下面还写一写离线处理的代码,随后跟上。
hdu 5057 Argestes and Sequence
标签:des style http color io os ar java strong
原文地址:http://blog.csdn.net/knight_kaka/article/details/39699263