链接:https://ac.nowcoder.com/acm/contest/26896/1033
来源:牛客网
题目描述
HH有一串由各种漂亮的贝壳组成的项链。
HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一 段贝壳,思考它们所表达的含义。
HH不断地收集新的贝壳,因此他的项链变得越来越长。
有一天,他突然提出了一 个问题:某一段贝壳中,包含了多少种不同的贝壳?
这个问题很难回答。。。因为项链实在是太长了。于是,他只 好求助睿智的你,来解决这个问题。
输入描述:
第一行:一个整数N,表示项链的长度。
第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的整数)。
第三行:一个整数M,表示HH询问的个数。
接下来M行:每行两个整数,L和R(1 ≤ L ≤ R ≤ N),表示询问的区间。
N ≤ 50000,M ≤ 200000。
输出描述:
M行,每行一个整数,依次表示询问对应的答案。
示例1
输入
6 1 2 3 4 3 5 3 1 2 3 5 2 6
输出
2 2 4
备注:
对于20%的数据,1≤n,m≤50001/le n,m/leq 50001≤n,m≤5000;
对于40%的数据,1≤n,m≤1051/le n,m/leq 10^51≤n,m≤105;
对于60%的数据,1≤n,m≤5×1051/le n,m/leq 5/times 10^51≤n,m≤5×105;
对于100%的数据,1≤n,m,ai≤106,1≤l≤r≤n1/le n,m,a_i /leq 10^6,1/le l /le r /le n1≤n,m,ai≤106,1≤l≤r≤n。
本题可能需要较快的读入方式,最大数据点读入数据约 20MB
分析
题意是查询每个区间有多少种不同的数
区间操作,考虑树状数组,
一开始考虑离线操作,按右端点递增顺序排序区间,然后 遍历所有位置,以右端点为顶点,求所有区间内的数的种数。然后就卡在求区间内的种数怎么求这个问题上了
思路是对的,但遍历所有位置并没有意义,因为对于所有不同的左端点,没办法确定区间内的数的种数,除非临时更改,但这样复杂度又变成了n^2。而且最关键的是,当时想的是将数组的值放到树状数组上,而不是位置。
其实可以考虑到了当前区间右端点,将所有该右端点之前已经出现的数都考虑到数组上,并且对于同种大小的数只记录它最后出现的位置。
取一个last数组,就可以实现,如果last数组已经存了这个数上一次出现的位置,就把上一次出现的位置删除,并加入这一次出现的位置。
//-------------------------代码---------------------------- //#define int ll const int N = 1e6+10; int n,m; int a[N],ans[N],last[N],tr[N]; struct node { int id,l,r; bool operator<(node &w){ return r<w.r; } }p[N]; void add(int x,int c) {for(int i=x;i<N;i+=lowbit(i))tr[i]+=c;} int sum(int x) {int res = 0;for(int i = x;i;i-=lowbit(i))res += tr[i];return res;} void solve() { // cin>>n>>m; cin>>n; fo(i,1,n) { cin>>a[i]; } cin>>m; fo(i,1,m) { int l,r;cin>>l>>r; p[i] = {i,l,r}; } sort(p+1,p+1+m);int j = 1; fo(i,1,m) { while(j <= p[i].r) { if(last[a[j]]) add(last[a[j]],-1); add(j,1); last[a[j]] = j; j ++ ; } ans[p[i].id] = sum(p[i].r) - sum(p[i].l-1); } fo(i,1,m) cout<<ans[i]<<endl; } void main_init() {} signed main(){ AC();clapping();TLE; cout<<fixed<<setprecision(12); main_init(); // while(cin>>n,n) // while(cin>>n>>m,n,m) // int t;cin>>t;while(t -- ) solve(); // {solve(); } return 0; } /*样例区 */ //------------------------------------------------------------
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/280222.html