4 1 1 1 1 14 2 1 2 2 2 3 2 4 1 2 3 1 2 2 1 2 2 2 3 2 4 1 1 4 2 1 2 1 2 2 2 3 2 4
1 1 1 1 1 3 3 1 2 3 4 1
终于把区间更新搞明白了,书上的写法实在是晦涩难懂,明明是区间更新,干嘛非要生搬硬套单点更新的写法??区间更新,带入函数的参数是向下管理从1到这个点的所有区域的,而单点更新,已知了一个点,管理这个点的高层们都需要更新自己的值,这就是本质区别,而且选择适合的算法时间也要稍微快一点
/************* hdu4267 2016.2.1 483MS 29952K 1447 B G++old 374MS 29796K 1390 B G++new *************/ #include<cstdio> #include<cstring> using namespace std; int n,q,c[12][12][50010],tmp[50010]; int lowbit(int i) { return i&(-i); } void add(int t1,int t2,int i,int x) { while(i>0) { c[t1][t2][i]+=x; i-=lowbit(i); } } int query(int t1,int t2,int x) { int s=0; while(x<=n) { s+=c[t1][t2][x]; x+=lowbit(x); } return s; } int main() { //freopen("cin.txt","r",stdin); while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); int a,b,k,e,m; for(int i=1;i<=n;i++) { scanf("%d",&tmp[i]); } // for(int i=1;i<=n;i++) printf("%d ",c[i]); scanf("%d",&q); while(q--) { scanf("%d",&m); if(m==1) { scanf("%d%d%d%d",&a,&b,&k,&e); int num=(b-a)/k; int s=a%k; add(k,s,a-1,-e); add(k,s,b,e); } else { scanf("%d",&a); int sum=tmp[a]; for(int i=1;i<=10;i++) { sum+=query(i,a%i,a); } printf("%d\n",sum); } } } return 0; }
/************* hdu4267 2016.2.1 *************/ #include <iostream> #include<cstdio> #include<cstring> using namespace std; int n,q,c[12][12][50010],tmp[50010]; int lowbit(int i) { return i&(-i); } void add(int t1,int t2,int i,int x) { while(i<=n) { c[t1][t2][i]+=x; i+=lowbit(i); } } int query(int t1,int t2,int x) { int s=0; while(x>0) { s+=c[t1][t2][x]; x-=lowbit(x); } return s; } int main() { //freopen("cin.txt","r",stdin); while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); int a,b,k,e,m; for(int i=0;i<n;i++) { scanf("%d",&tmp[i]); } // for(int i=1;i<=n;i++) printf("%d ",c[i]); scanf("%d",&q); while(q--) { scanf("%d",&m); if(m==1) { scanf("%d%d%d%d",&a,&b,&k,&e); a--;b--; int num=(b-a)/k; int s=a%k; add(k,s,a/k+1,e); add(k,s,a/k+num+2,-e); } else { scanf("%d",&a); a--; int sum=tmp[a]; for(int i=1;i<=10;i++) { sum+=query(i,a%i,a/i+1); } printf("%d\n",sum); } } } return 0; }