zoukankan      html  css  js  c++  java
  • 树状数组操作

    [SDOI2009]HH的项链

    题意:序列(n <= 1e6),有(m <= n)个询问,求(l)(r)中有几个不相同的数。
    题解:如果(n)的范围为(1e5)就是莫队裸题,但是由于(n)的范围为(1e6)那么就是可用树状数组操作,具体就是可发现,只有最后出现的数字有价值,设(r)指针从左到右,如果出现了一个数之前没出现过,在树状数组里此位置(+1),如果当前(r)的数出现过,那么就是之前的位置在树状数组中(-1),然后新的位置(+1),然后询问的话,就是(sum(r)-sum(l-1))就是区间([l,r])的不同数的数量
    代码:

    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #include <cstdio>
    
    using namespace std;
    typedef long long ll;
    
    const int N = 1000010,  M = 1000010, S = 1000010;
    ll lowbit(ll x) {
    	return -x&x;
    }
    int n;
    struct BIT {
    	int d[N], Pos[N];
    	ll ask(ll pos) {ll ret = 0;while (pos>0) {ret += d[pos],pos -= lowbit(pos);}return ret;}
    	void add(ll pos, ll add){while (pos <= n)d[pos]+=add,pos+=lowbit(pos);}
    }bit;
    int a[N];
    struct query {
    	int id,l, r;
    }q[M];
    ll ans[N];
    bool cmp(query a, query b) {
    	return a.r < b.r;
    }
    signed main() {
    	scanf("%d",&n);
    	for (int i = 1; i <= n; i++) 
    	{
    		scanf("%d", &a[i]);
    	}
    	int m;scanf("%d", &m);
    	for (int i = 1; i <= m; i++) {
    		int l, r;
    		scanf("%d%d",&l,&r);
    		q[i] = {i, l, r};
    	}
    	sort(q + 1, q + 1 +m, cmp);
    //	for (int i = 1; i <= m; i++) {
    //		cout << q[i].l << " " << q[i].r << endl;
    //	}
    	for (int i = 1, j = 1; i <= m; i++) {
    		int id = q[i].id, l = q[i].l, r = q[i].r;
    		
    		while ( j <= r ) {
    			int now = a[j];
    			//cout << "j:" << j << " " << "now:" << now << "  " << bit.Pos[now] << endl;
    			if (bit.Pos[now] == 0) {
    				bit.add(j, 1);
    				//cout << "add" << j << " 1
    ";
    				bit.Pos[now] = j;
    			} else {
    				bit.add(bit.Pos[now], -1);
    				//cout << "add" << bit.Pos[now] << " " << -1 << endl;
    				//cout << "add" << j << " 1
    ";
    				bit.add(j, 1);
    				bit.Pos[now] = j;
    			}
    			//cout << bit.ask(j) << endl;
    			j++;
    		} 
    		//cout << l << "->" << r << endl;
    //		for (int ii = 0; ii <= n; ii++) {
    //			cout <<"ii:" << ii << " " << bit.ask(ii) << endl;
    //		}
    		ans[id] = bit.ask(r) - bit.ask(l-1);
    	//	cout << "ans" << " " << ans[id] << endl;
    	}
    	for (int i  =1;  i <= m; i++) {
    		printf("%d
    ", ans[i]);
    	}
     	return 0;
    } 
    
  • 相关阅读:
    数据库操作语句大全(sql)
    尚未在 Web 服务器上注册ASP.NET 4.5。安装VS15后的问题(转)
    ASP.NET通过http/https的POST方式,发送和接受XML文件内容(转)
    C# 的关键字详细介绍(转)
    12个css高级技巧.html
    CentOS上安装elasticsearch
    springboot例子
    ajax的XmlHttpRequest对象常用方法
    阿里云oss操作
    Python出现Could not find a version that satisfies the requirement openpyxl (from versions: )
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/14433014.html
Copyright © 2011-2022 走看看