链接

算是裸线段树了,因为没个数最多开63次 ,开到不能再看就标记。查询时,如果某段区间被标记直接返回结果,否则继续向儿子节点更新。

注意用——int64

注意L会大于R 这点我很纠结。。您出题人故意的吗 WAn次。。

hdu4027Can you answer these queries?(线段树)_#includehdu4027Can you answer these queries?(线段树)_#define_02
  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 100010
 12 #define LL __int64
 13 #define INF 0xfffffff
 14 const double eps = 1e-8;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17 LL s[N<<2],f[N<<2];
 18 LL a[N];
 19 void up(int w)
 20 {
 21     s[w] =s[w<<1]+s[w<<1|1];
 22     f[w] = (f[w<<1]&&f[w<<1|1]);
 23 }
 24 void build(int l,int r,int w)
 25 {
 26     if(l==r)
 27     {
 28         s[w] = a[l];
 29         if(a[l]==1||a[l]==0) f[w] = 1;
 30         return ;
 31     }
 32     int m = (l+r)>>1;
 33     build(l,m,w<<1);
 34     build(m+1,r,w<<1|1);
 35     up(w);
 36 }
 37 void update(int a,int b,int l,int r,int w)
 38 {
 39     if(a<=l&&b>=r)
 40     {
 41         if(l==r)
 42         {
 43             LL k = sqrt(s[w]*1.0);
 44             if(k*k>s[w])
 45             k--;
 46             s[w] = k;
 47             if(s[w]<=1)
 48             f[w] = 1;
 49            // up(w);
 50             return ;
 51         }
 52         if(f[w])
 53         {
 54             up(w);
 55             return ;
 56         }
 57         else
 58         {
 59             int m = (l+r)>>1;
 60             if(a<=m)
 61             update(a,b,l,m,w<<1);
 62             if(b>m)
 63             update(a,b,m+1,r,w<<1|1);
 64             up(w);
 65             return ;
 66         }
 67     }
 68     int m  = (l+r)>>1;
 69     if(a<=m)
 70     update(a,b,l,m,w<<1);
 71     if(b>m)
 72     update(a,b,m+1,r,w<<1|1);
 73     up(w);
 74 }
 75 LL query(int a,int b,int l,int r,int w)
 76 {
 77     if(a<=l&&b>=r)
 78     {
 79         return s[w];
 80     }
 81     int m = (l+r)>>1;
 82     LL res = 0;
 83     if(a<=m) res+=query(a,b,l,m,w<<1);
 84     if(b>m) res+=query(a,b,m+1,r,w<<1|1);
 85     return res;
 86 }
 87 int main()
 88 {
 89     int i,n,q;
 90     int k,x,y,kk=0;
 91     while(scanf("%d",&n)!=EOF)
 92     {
 93         memset(f,0,sizeof(f));
 94         for(i = 1; i <=n ;i++)
 95         {
 96             scanf("%I64d",&a[i]);
 97         }
 98         build(1,n,1);
 99         scanf("%d",&q);
100         printf("Case #%d:\n",++kk);
101         while(q--)
102         {
103             scanf("%d%d%d",&k,&x,&y);
104             if(x>y) swap(x,y);
105             if(k)
106             {
107                 printf("%I64d\n",query(x,y,1,n,1));
108             }
109             else
110             {
111                 update(x,y,1,n,1);
112             }
113         }
114         puts("");
115     }
116     return 0;
117 }
View Code