HDU 3874 Necklace 区间查询的离线操作
2014-08-05 04:19
295 查看
题目: 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]的点完全可以舍弃-----------------原来先排序的处理方式还有个专业名字叫=======离线操作
话不多说,看代码:
View Code
对需要查询的区间按右端点排序,然后从左到右依次加入序列中的元素,同时更新,更新的方法是,把上一次出现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]的点完全可以舍弃-----------------原来先排序的处理方式还有个专业名字叫=======离线操作
话不多说,看代码:
/********************************************** *** Problem: *** Author: JKL *** University: CSUST *** Team: __Dream *** Email: 1451108308@QQ.COM *** My Blog: http://www.cnblogs.com/jklongint/ ***********************************************/ //=================================================== #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <cstdio> #include <cstdlib> #include <cmath> #include <cassert> #include <numeric> #include <ctime> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <queue> #include <map> #include <stack> #include <list> #include <set> #include <bitset> #include <deque> using namespace std; //--------------------------------------------------- #define mem(a,b) memset(a,b,sizeof(a)) #define GO cout<<"HelloWorld!"<<endl #define Case(x) cout<<"Case "<<x<<":" #define foru(i,n) for(int i=1; i <= n; i++) #define ford(i,n) for(int i = n; i >= 1; i--) #define fin freopen("input.txt","r",stdin); #define fout freopen("output.txt","w",stdout) #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 #define sqr(a) ((a)*(a)) #define abs(a) ((a>0)?(a):-(a)) #define pii pair<int,int> #define fmax(a,b) max(a,b) #define fmin(a,b) min(a,b) #define fmax3(a,b,c) (fmax(a,fmax(a,b))) #define fmin3(a,b,c) (fmin(a,fmin(a,b))) #define sfi(x) scanf("%d",&x) #define sfL(x) scanf("%I64d",&x) #define sfc(x) scanf("%c",&x) #define sfd(x) scanf("%lf",&x) #define sfs(x) scanf("%s",x) #define sfii(a,b) scanf("%d%d",&a,&b) #define sfLL(a,b) scanf("%I64d%I64d",&a,&b) #define sfcc(a,b) scanf("%c%c",&a,&b) #define sfdd(a,b) scanf("%lf%lf",&a,&b) #define sfss(a,b) scanf("%s%s",a,b) #define pfi(x) printf("%d",x) #define pfL(x) printf("%I64d",x) #define pfs(x) printf("%s",x) #define pfd(x) printf("%lf",x) #define pfc(x) print("%c",x) #define newLine pfs("\n") #define space pfs(" ") //-------------------------------------------------------- typedef __int64 LL; typedef unsigned long long ULL; //typedef __int64 __LL; typedef unsigned __int64 __ULL; typedef vector<int> vi; typedef vector<LL> vL; typedef vector<string> vs; typedef set<int> si; typedef map<int,int> mii; typedef map<LL,LL> mLL; typedef map<string,int> msi; typedef map<char,int> mci; //-------------------------------------------------------- const int dx[4]={1,-1,0,0}; const int dy[4]={0,0,1,-1}; const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; const int N6=1000006; const int N5=100006; const int N4=10006; const int N3=1006; const int N2=106; const int N=210009; const int MOD=1000000007; const LL LMAX=0x7fffffffffffffff; const LL IMAX=0x3fffffff; const double PI=3.14159265359; //-------------------------------------------------------- template< class T > T gcd(T a, T b) { return (b != 0 ? gcd<T>(b, a%b) : a); } template< class T > T lcm(T a, T b) { return (a / gcd<T>(a, b) * b); } //------------------------------------------------------------ struct TreeNode{ LL sum; }; struct Node{ int l, r, id; }; //================================================================= TreeNode tree[N << 2]; Node node ; int a , last[1000009]; LL ans ; int cmp(Node i, Node j) { return i.r < j.r ; } void PushUP(int rt) { tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum; } void update(int p, int x, int l , int r, int rt) { if(l == r){ tree[rt].sum += x; return; } int m = (l + r) >> 1; if(p <= m)update(p, x, lson); else update(p, x, rson); PushUP(rt); } LL query(int L, int R, int l, int r, int rt) { if(L <= l && R >= r){ return tree[rt].sum; } int m = (l + r) >> 1; LL res = 0; if(L <= m) res += query(L, R, lson); if(R > m) res += query(L, R, rson); return res; } void build(int l, int r, int rt) { if(l == r){ tree[rt].sum = 0; return; } int m = (l + r) >> 1; build(lson); build(rson); PushUP(rt); } int main() { //fin;//fout;//freopen("input.txt","r",stdin); int n, m, T; cin >> T; while(T--){ cin >> n ; foru(i, n)sfi(a[i]); cin >> m; foru(i, m)sfii(node[i].l, node[i].r),node[i].id = i; sort(node + 1, node + 1 + m, cmp); build(1, n, 1); int np = 1; mem(last, 0); foru(i, n){ if(last[a[i]])update(last[a[i]], -a[i], 1, n, 1); update(i, a[i], 1, n, 1); while(node[np].r == i && np <= m){ ans[node[np].id] = query(node[np].l, node[np].r, 1, n, 1); np++; } last[a[i]] = i; } foru(i, m)pfL(ans[i]),newLine; } return 0; }
View Code
相关文章推荐
- HDU 3874 Necklace (线段树单点更新+区间查询+离线操作)
- HDU - 3874 Necklace(树状数组+离线操作)
- hdu 3874 Necklace(离线操作+树状数组或线段树)
- HDU 3874 Necklace(树状数组的离线操作)
- hdu 3874 Necklace (树状数组+离线操作)
- HDU 3874 Necklace (树状数组+离线操作)
- HDU 3874 Necklace(树状数组的离线操作)
- Necklace (线段树单点更新+区间查询+离线操作)
- hdu 3874 Necklace 树状数组 离线操作
- HDU - 3874Necklace(线段树离线查询)
- hdu 3874 Necklace(bit树+事先对查询区间右端点排序)
- HDU 3874 Necklace 离线+树状数组
- HDOJ 题目3874 Necklace(线段树+离线求区间去重和)
- HDU 3874 Necklace&&HDU 3333 Turing Tree(求一些区间l~r中的数去重后的和)
- SPOJ3267 D-Query 树状数组离线操作 或 主席树 查询某一区间内有多少不同的数
- HDU-3874 Necklace 线段树+离线
- HDU 3874 Necklace(树状数组离线处理)
- HDU - 3874 Necklace (线段树 + 离线处理)
- hdu5493(线段树,离线操作,点修改,区间查询)
- hdu 3874 Necklace 线段树单点更新区间求和