您的位置:首页 > 其它

HDU 4267 A Simple Problem with Integers

2014-08-18 10:31 375 查看
题目大意:

   两种操作:

         1.a,b,k,v      对于下标i, a<=i<=b ,(i-a)%k==0,num[i]+=v;


         2.a               求a位置数值的大小

解决方法:

    由于修改的区间不是连续的所以不太好处理,但是有题目中给出的k的范围很小,所以我们可以建立多个线段树进行维护。

    10>=k>=0 所以建立55个线段树,tree[55][maxn],并且做好标志数组vis[k][j],其表示i%k==j的标记为多少,i代表当前位置。

    (i-a)%k==0 等价于 i%k=a%k,所以求某个点就相当于求   for (int i=0;i<=10;i++)  sum+=tree[vis[k][a%k]][o];当然这仅仅是一个节点的处理,我们应该对经过的每个节点都进行上述处理,最终得到的sum就是结果。

    修改的操作类似与查询。

我的代码:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <cstdio>
#define maxn 50050
using namespace std;
int vis[11][11];
int tree[maxn*3][55];
int num[maxn];
int build (int o,int L,int R){
if (L==R){
memset(tree[o],0,sizeof(tree[o]));
}
else {
memset(tree[o],0,sizeof(tree[o]));
int M=L+(R-L)/2;
build (o*2,L,M);
build (o*2+1,M+1,R);
}
return 0;
}
int y1,y2,k,d;
int changque(int o,int L,int R){
if (y1<=L&&y2>=R){
tree[o][vis[k][y1%k]]+=d;
}
else {
int M=L+(R-L)/2;
if (y1<=M) changque(o*2,L,M);
if (y2>M) changque(o*2+1,M+1,R);
}
return 0;
}
int yy,_sum;
int query(int o,int L,int R){
if (L==R&&L==yy){
for (int i=1;i<=10;i++)
_sum+=tree[o][vis[i][yy%i]];
}
else {
for (int i=1;i<=10;i++)
_sum+=tree[o][vis[i][yy%i]];
int M=L+(R-L)/2;
if (yy<=M) query(o*2,L,M);
if (yy>M) query(o*2+1,M+1,R);
}
return 0;
}
int main (){
//freopen("test.in","r",stdin);
memset(vis,0,sizeof(vis));
int totl=0;
for (int i=1;i<=10;i++)
for (int j=0;j<i;j++)
vis[i][j]=totl++;
int n,m;
while (~scanf("%d",&n)){
for (int i=1;i<=n;i++)
scanf("%d",&num[i]);
build(1,1,n);
scanf("%d",&m);
for (int i=0;i<m;i++){
int po; scanf("%d",&po);
if (po==2) {
scanf("%d",&yy);
_sum=0;
query(1,1,n);
printf("%d\n",_sum+num[yy]);
}
else {
scanf("%d%d%d%d",&y1,&y2,&k,&d);
changque(1,1,n);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: