POJ3468---A Simple Problem with Integers

此题简单的做法自然是 线段树 或树状数组,splay只是为了练手。。依旧 是学习bin神的模板,写了一发之后理解更深了。

  1 #include <set>

  2 #include <map>

  3 #include <cmath>

  4 #include <ctime>

  5 #include <queue>

  6 #include <stack>

  7 #include <cstdio>

  8 #include <string>

  9 #include <vector>

 10 #include <cstdlib>

 11 #include <cstring>

 12 #include <iostream>

 13 #include <algorithm>

 14 using namespace std;

 15 typedef unsigned long long ull;

 16 typedef long long ll;

 17 const int inf = 0x3f3f3f3f;

 18 const double eps = 1e-8;

 19 const int maxn = 1e5+100;

 20 ll add[maxn],sum[maxn];

 21 int ch[maxn][2],siz[maxn],key[maxn],a[maxn];

 22 int pre[maxn];

 23 int tot1,root;

 24 void new_node(int &r,int father,int k)

 25 {

 26     r = ++tot1;

 27     pre[r] = father;

 28     siz[r] = 1;

 29     add[r] = 0;

 30     key[r] = k;

 31     sum[r] = k;

 32     ch[r][0] = ch[r][1] = 0;

 33 }

 34 

 35 void update(int r,int val)

 36 {

 37     if (r == 0)

 38         return ;

 39     add[r] += val;

 40     key[r] += val;

 41     sum[r] += (ll)val * siz[r];

 42 }

 43 

 44 void push_down(int x)

 45 {

 46     if (add[x])

 47     {

 48         update(ch[x][0],add[x]);

 49         update(ch[x][1],add[x]);

 50         add[x] = 0;

 51     }

 52 }

 53 void push_up(int x)

 54 {

 55     siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;

 56     sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + key[x];

 57 }

 58 void build(int &x,int l,int r,int father)

 59 {

 60     if (l > r)

 61         return;

 62     int mid = (l + r) >> 1;

 63     new_node(x,father,a[mid-1]);

 64     build(ch[x][0],l,mid-1,x);

 65     build(ch[x][1],mid+1,r,x);

 66     push_up(x);

 67 }

 68 void init(int n)

 69 {

 70     tot1 = 0;

 71     root = 0;

 72     new_node(root,0,-1);

 73     new_node(ch[root][1],root,-1);

 74     for (int i = 0; i < n; i++)

 75         scanf ("%d",a+i);

 76     build(ch[ch[root][1]][0],1,n,ch[root][1]);

 77     push_up(ch[root][1]);

 78     push_up(root);

 79 }

 80 void Rotate(int x,int kind)

 81 {

 82     int y = pre[x];

 83     push_down(y);

 84     push_down(x);              // 标记下传

 85 

 86     ch[y][!kind] = ch[x][kind];

 87     pre[ch[x][kind]] = y;

 88     ch[x][kind] = y;

 89     if (pre[y])

 90         ch[pre[y]][ch[pre[y]][1] == y] = x;

 91     pre[x] = pre[y];

 92     pre[y] = x;

 93     push_up(y);               //     ???

 94 }

 95 void Splay(int r,int goal)

 96 {

 97     push_down(r);

 98     while (pre[r] != goal)

 99     {

100         if (pre[pre[r]] == goal)

101             Rotate(r,ch[pre[r]][0] == r);

102         else

103         {

104             int y = pre[r];

105             int kind = (ch[pre[y]][0] == y);

106             if (ch[y][kind] == r)

107             {

108                 Rotate(r,!kind);

109                 Rotate(r,kind);

110             }

111             else

112             {

113                 Rotate(y,kind);

114                 Rotate(r,kind);

115             }

116         }

117     }

118     push_up(r);

119     if (goal == 0)

120         root = r;

121 }

122 int Get_kth(int r,int k)

123 {

124     push_down(r);

125     int t = siz[ch[r][0]] + 1;

126     if (k == t)

127         return r;

128     if (t > k)

129         Get_kth(ch[r][0],k);

130     else

131         Get_kth(ch[r][1],k-t);

132 }

133 void ADD(int l,int r,int val)

134 {

135     Splay(Get_kth(root,l),0);

136     Splay(Get_kth(root,r+2),root);

137     update(ch[ch[root][1]][0],val);

138     push_up(ch[root][1]);

139     push_up(root);

140 }

141 ll query(int l,int r)

142 {

143     Splay(Get_kth(root,l),0);

144     Splay(Get_kth(root,r+2),root);

145     return sum[ch[ch[root][1]][0]];

146 }

147 int main(void)

148 {

149     #ifndef ONLINE_JUDGE

150         freopen("in.txt","r",stdin);

151     #endif

152     int n,q;

153     while (~scanf ("%d%d",&n,&q))

154     {

155         init(n);

156         char op[8];

157         while (q--)

158         {

159             scanf ("%s",op);

160             if (op[0] == 'C')

161             {

162                 int x,y,v;

163                 scanf ("%d%d%d",&x,&y,&v);

164                 ADD(x,y,v);

165             }

166             if (op[0] == 'Q')

167             {

168                 int x,y;

169                 scanf ("%d%d",&x,&y);

170                 printf("%lld\n",query(x,y));

171             }

172         }

173     }

174     return 0;

175 }
View Code

 

你可能感兴趣的:(Integer)