hdu 4267

一个很不错的题;

刚刚看到这个题目就感觉要用线段树或者树状数组,但是有感觉有点不同;

敲了一发简单的线段树之后果断的T了;

网上一搜题解,发现要用55颗线段树或者树状数组;

一共有k种树,然后每种树根据他们%k的余数的不同又分成好几颗;

然后最后统计的时候只要对每个节点统计这k种树种的信息就行;

 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxn 50005
 4 using namespace std;
 5 
 6 int d[100][maxn],num[maxn];
 7 int n,q;
 8 void insert(int k,int p,int v)
 9 {
10     while(p<=n)
11     {
12         d[k][p]+=v;
13         p+=p&-p;
14     }
15 }
16 
17 int query(int p)
18 {
19     int ret=0;
20     for(int i=0; i<10; i++)
21     {
22         int k=i*10+p%(i+1);
23         for(int j=p; j>0; j-=j&-j)ret+=d[k][j];
24     }
25     return num[p]+ret;
26 }
27 
28 int main()
29 {
30     int cmd,a,b,k,c;
31     while(scanf("%d",&n)!=EOF)
32     {
33         memset(d,0,sizeof d);
34         for(int i=1; i<=n; i++)scanf("%d",&num[i]);
35         scanf("%d",&q);
36         for(int i=0; i<q; i++)
37         {
38             scanf("%d",&cmd);
39             if(cmd==1)
40             {
41                 scanf("%d%d%d%d",&a,&b,&k,&c);
42                 b-=(b-a)%k;
43                 int p=(k-1)*10+a%k;
44                 insert(p,a,c);
45                 insert(p,b+1,-c);
46             }
47             else
48             {
49                 scanf("%d",&a);
50                 printf("%d
",query(a));
51             }
52         }
53     }
54     return 0;
55 }
View Code
原文地址:https://www.cnblogs.com/yours1103/p/3419845.html