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: 1451108308@QQ.COM 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 }