BZOJ1878: [SDOI2009]HH的项链(树状数组+离线)
2016-10-19 22:03
330 查看
Description HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。 Input 第一行:一个整数N,表示项链的长度。 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。 第三行:一个整数M,表示HH询问的个数。 接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。 Output M行,每行一个整数,依次表示询问对应的答案。 Sample Input 6 1 2 3 4 3 5 3 1 2 3 5 2 6 Sample Output 2 2 4 HINT 对于20%的数据,N ≤ 100,M ≤ 1000; 对于40%的数据,N ≤ 3000,M ≤ 200000; 对于100%的数据,N ≤ 50000,M ≤ 200000。
先mark一下莫队算法(不会)。 说一下我的理解吧。 这里只涉及区间查询有多少个不同值的运算,没有涉及其他修改的操作,我们可以采取离线做法。 首先呢,我们按右边界点排序(方便操作). 然后我们记录用last[i]记录某个数字最后出现的位置,pre[i]记录某个数字之前是否有出现过,没出现过则为0. 这里我们主要以某个数字的第一次出现的点代表该数字(之后无论出现多少次都以第一次出现的该数字为主). 我们从1开始算,即(1~500000,从1算到500000),这里我们只需要统计到当前所给最大的右边界就行了(1~maxR)。 [l,r]如果多次出现某个相同的数字(并且在l之前从未出现过这个数字即pre[i]=0),我们就以第一个该数字为主(肯定在l之前被统计,这就是为什么最后统计的是左边界就好了). ----扫描左端点-------------------------------------------- 总结:离线做法
#include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> #include<cmath> #include<ctime> #include<string> #include<stack> #include<deque> #include<queue> #include<list> #include<set> #include<map> #include<cstdio> #include<limits.h> #define MOD 1000000007 #define fir first #define sec second #define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin) #define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout) #define mes(x, m) memset(x, m, sizeof(x)) #define Pii pair<int, int> #define Pll pair<ll, ll> #define INF 1e9+7 #define Pi 4.0*atan(1.0) #define lowbit(x) (x&(-x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; typedef unsigned long long ull; const double eps = 1e-12; const int maxn = 50010; const int maxm = 200010; using namespace std; inline int read(){ int x(0),f(1); char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int N,M; int last[1000010],pre[1000010]; int sum[maxn],ans[maxm]; struct Sq{ int l,r,pos; bool operator<(const Sq&t)const{ return r<t.r; } }sq[maxm]; inline void update(int i,int val) { while(i<=N){ sum[i]+=val; i+=lowbit(i); } } inline int query(int i) { int res=0; while(i){ res+=sum[i]; i-=lowbit(i); } return res; } void solve() { int t; N=read(); mes(last,0); for(int i=1;i<=N;++i){ t=read(); pre[i]=last[t]; last[t]=i; } M=read(); for(int i=1;i<=M;++i){ sq[i].l=read(),sq[i].r=read(); sq[i].pos=i; } stable_sort(sq,sq+M+1); /* for(int i=1;i<=M;++i){ cout<<sq[i].l<<" "<<sq[i].r<<endl; }*/ int cur=0; for(int i=1;i<=M;++i){ while(cur<sq[i].r){ ++cur; update(pre[cur]+1,1); update(cur+1,-1); } ans[sq[i].pos]=query(sq[i].l); } for(int i=1;i<=M;++i){ printf("%d\n",ans[i]); } } int main() { //fin; solve(); }
相关文章推荐
- 【bzoj1878】[SDOI2009]HH的项链 树状数组+离线
- 【bzoj 1878】[SDOI2009]HH的项链
- [SDOI2009][BZOJ1878][前缀和][树状数组]HH的项链
- bzoj1878: [SDOI2009]HH的项链(树状数组+离线处理)
- BZOJ 1878 [SDOI2009]HH的项链 离线+树状数组
- bzoj 1878 [SDOI2009]HH的项链(离线处理+BIT)
- bzoj千题计划181:bzoj1878: [SDOI2009]HH的项链
- 【主席树|莫队|离线树状数组】BZOJ1878 [SDOI 2009]HH的项链
- 【bzoj1878】[SDOI2009]HH的项链
- 【bzoj1878】[SDOI2009]HH的项链
- bzoj1878 [SDOI2009]HH的项链
- [BZOJ 1878] [SDOI2009] HH的项链
- [bzoj1878][SDOI2009]HH的项链_树状数组
- BZOJ1878: [SDOI2009]HH的项链
- bzoj1878 [SDOI2009]HH的项链
- BZOJ-1878-HH的项链-SDOI2009
- 【bzoj1878】【洛谷P1972】【SDOI2009】HH的项链
- 【SDOI2009】bzoj1878 HH的项链【解法二】
- bzoj 1878 [SDOI2009]HH的项链 树状数组 离线查询
- bzoj1878 [SDOI2009]HH的项链【莫队】