HDU 3874 Necklace 区间查询的离线操作

题目: http://acm.hdu.edu.cn/showproblem.php?pid=3874

对需要查询的区间按右端点排序,然后从左到右依次加入序列中的元素,同时更新,更新的方法是,把上一次出现a[i]值的点变为0,这一次a[i]值的点(即 i)变为a[i],这样保证了前i个元素中只存在一个等于a[i]值得元素,那为什么这样不会影响后面的查询呢?

因为是处理到i点,则把右边界等于a[i]的查询处理掉,剩下的待查询的区间右边界在i点之后,如果左边界在i之前,那么也会包含i点,也就包含了i点的值,由于i以前没有等于a[i]的点,所以只包含了一个这样的值,如果左边界在i之后,前面的操作对它就没影响了。也可以这样理解,当前处理到i点,如果后面的待查询区间的左边界要包含上一个值为a[i]的点,那么它必须也包含了i点,所以i之前等于a[i]的点完全可以舍弃-----------------原来先排序的处理方式还有个专业名字叫=======离线操作

话不多说,看代码:

  1 /**********************************************

  2 ***    Problem:

  3 ***    Author:        JKL

  4 ***    University:    CSUST

  5 ***    Team:          __Dream

  6 ***    Email:          [email protected]

  7 ***    My Blog:        http://www.cnblogs.com/jklongint/

  8 ***********************************************/

  9 //===================================================

 10 #include <iostream>

 11 #include <fstream>

 12 #include <sstream>

 13 #include <iomanip>

 14 #include <cstdio>

 15 #include <cstdlib>

 16 #include <cmath>

 17 #include <cassert>

 18 #include <numeric>

 19 #include <ctime>

 20 #include <algorithm>

 21 #include <cstring>

 22 #include <string>

 23 #include <vector>

 24 #include <queue>

 25 #include <map>

 26 #include <stack>

 27 #include <list>

 28 #include <set>

 29 #include <bitset>

 30 #include <deque>

 31 using namespace std;

 32 //---------------------------------------------------

 33 #define mem(a,b) memset(a,b,sizeof(a))

 34 #define GO cout<<"HelloWorld!"<<endl

 35 #define Case(x) cout<<"Case "<<x<<":"

 36 #define foru(i,n) for(int i=1; i <= n; i++)

 37 #define ford(i,n) for(int i = n; i >= 1; i--)

 38  #define fin freopen("input.txt","r",stdin);

 39  #define fout freopen("output.txt","w",stdout)

 40 #define lson  l, m, rt << 1

 41 #define rson  m + 1, r, rt << 1 | 1

 42 

 43 #define sqr(a)  ((a)*(a))

 44 #define abs(a) ((a>0)?(a):-(a))

 45 #define pii pair<int,int>

 46 

 47 #define fmax(a,b) max(a,b)

 48 #define fmin(a,b) min(a,b)

 49 #define fmax3(a,b,c)  (fmax(a,fmax(a,b)))

 50 #define fmin3(a,b,c)  (fmin(a,fmin(a,b)))

 51 

 52 #define sfi(x) scanf("%d",&x)

 53 #define sfL(x) scanf("%I64d",&x)

 54 #define sfc(x) scanf("%c",&x)

 55 #define sfd(x) scanf("%lf",&x)

 56 #define sfs(x) scanf("%s",x)

 57 #define sfii(a,b) scanf("%d%d",&a,&b)

 58 #define sfLL(a,b) scanf("%I64d%I64d",&a,&b)

 59 #define sfcc(a,b) scanf("%c%c",&a,&b)

 60 #define sfdd(a,b) scanf("%lf%lf",&a,&b)

 61 #define sfss(a,b) scanf("%s%s",a,b)

 62 

 63 #define pfi(x) printf("%d",x)

 64 #define pfL(x) printf("%I64d",x)

 65 #define pfs(x) printf("%s",x)

 66 #define pfd(x) printf("%lf",x)

 67 #define pfc(x) print("%c",x)

 68 #define newLine pfs("\n")

 69 #define space pfs(" ")

 70 

 71 //--------------------------------------------------------

 72 typedef __int64 LL;

 73 typedef unsigned long long ULL;

 74 //typedef __int64 __LL;

 75 typedef unsigned __int64 __ULL;

 76 

 77 typedef vector<int> vi;

 78 typedef vector<LL> vL;

 79 typedef vector<string> vs;

 80 typedef set<int> si;

 81 typedef map<int,int> mii;

 82 typedef map<LL,LL> mLL;

 83 typedef map<string,int> msi;

 84 typedef map<char,int> mci;

 85 //--------------------------------------------------------

 86 const int dx[4]={1,-1,0,0};

 87 const int dy[4]={0,0,1,-1};

 88  const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};

 89  const int N6=1000006;

 90  const int N5=100006;

 91  const int N4=10006;

 92  const int N3=1006;

 93  const int N2=106;

 94  const int N=210009;

 95  const int MOD=1000000007;

 96  const LL LMAX=0x7fffffffffffffff;

 97  const LL IMAX=0x3fffffff;

 98  const double PI=3.14159265359;

 99 //--------------------------------------------------------

100 template< class T > T gcd(T a, T b) { return (b != 0 ? gcd<T>(b, a%b) : a); }

101 template< class T > T lcm(T a, T b) { return (a / gcd<T>(a, b) * b); }

102 

103 //------------------------------------------------------------

104 struct TreeNode{

105     LL  sum;

106 };

107 struct Node{

108     int l, r, id;

109 };

110 //=================================================================

111 TreeNode tree[N << 2];

112 Node node[N];

113 int  a[N], last[1000009];

114 LL ans[N];

115 int cmp(Node i, Node j)

116 {

117     return i.r < j.r ;

118 }

119 void PushUP(int rt)

120 {

121     tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;

122 }

123 void update(int p, int x, int l , int r, int rt)

124 {

125     if(l == r){

126         tree[rt].sum += x;

127         return;

128     }

129     int m = (l + r) >> 1;

130     if(p <= m)update(p, x, lson);

131     else update(p, x, rson);

132     PushUP(rt);

133 }

134 LL query(int L, int R, int l, int r, int rt)

135 {

136     if(L <= l && R >= r){

137         return tree[rt].sum;

138     }

139     int m = (l + r) >> 1;

140     LL res = 0;

141     if(L <= m) res += query(L, R, lson);

142     if(R > m) res += query(L, R, rson);

143     return res;

144 }

145 void build(int l, int r, int rt)

146 {

147     if(l == r){

148         tree[rt].sum = 0;

149         return;

150     }

151     int m = (l + r) >> 1;

152     build(lson);

153     build(rson);

154     PushUP(rt);

155 }

156 int main()

157 {

158     //fin;//fout;//freopen("input.txt","r",stdin);

159     int n, m, T;

160     cin >> T;

161     while(T--){

162         cin >> n ;

163         foru(i, n)sfi(a[i]);

164         cin >> m;

165         foru(i, m)sfii(node[i].l, node[i].r),node[i].id = i;

166         sort(node + 1, node + 1 + m, cmp);

167         build(1, n, 1);

168         int np = 1;

169         mem(last, 0);

170         foru(i, n){

171             if(last[a[i]])update(last[a[i]], -a[i], 1, n, 1);

172             update(i, a[i], 1, n, 1);

173             while(node[np].r == i && np <= m){

174                 ans[node[np].id] = query(node[np].l, node[np].r, 1, n, 1);

175                 np++;

176             }

177             last[a[i]] = i;

178         }

179         foru(i, m)pfL(ans[i]),newLine;

180     }

181     return 0;

182 }
View Code

 

你可能感兴趣的:(HDU)