zoukankan      html  css  js  c++  java
  • [bzoj2743][HEOI2012]采花_树状数组

    采花 bzoj-2743 HEOI-2012

    题目大意:给定n朵花,每朵花有一个种类,m次询问:一段区间中至少出现两朵花的种类的个数。

    注释:$1le n,mle10^6$。


    想法:这个题超级像HH的项链

    就是把那个题的$nxt$往后再延迟一个更新即可。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define RR register 
    #define N 1000010 
    using namespace std;
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
    int read()
    {
    	int x=0; char c=nc();
    	while(!isdigit(c)) c=nc();
    	while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=nc();
    	return x;
    }
    struct Node
    {
    	int l,r,id,ans;
    }q[N];
    int nxt[N],tree[N],a[N],p[N],n;
    inline bool cmp1(const Node &x,const Node &y)
    {
    	return x.l==y.l?x.r<y.r:x.l<y.l;
    }
    inline bool cmp2(const Node &x,const Node &y)
    {
    	return x.id<y.id;
    }
    inline int lowbit(int x) {return x&(-x);}
    void update(int x,int val)
    {
    	for(RR int i=x;i<=n+1;i+=lowbit(i))
    	{
    		tree[i]+=val;
    	}
    }
    int query(int x)
    {
    	int ans=0;
    	for(RR int i=x;i>=1;i-=lowbit(i))
    	{
    		ans+=tree[i];
    	}
    	return ans;
    }
    int main()
    {
    	n=read();
    	int mx=read(),m=read();
    	for(RR int i=1;i<=n;i++) a[i]=read();
    	for(RR int i=n;i>=1;i--)
    	{
    		nxt[i]=p[a[i]];
    		p[a[i]]=i;
    	}
    	for(RR int i=1;i<=mx;i++)
    	{
    		if(p[i]&&nxt[p[i]]) update(nxt[p[i]],1);
    	}
    	for(RR int i=1;i<=m;i++) q[i].l=read(),q[i].r=read(),q[i].id=i;
    	sort(q+1,q+m+1,cmp1);
    	int l=1;
    	for(RR int i=1;i<=m;i++)
    	{
    		while(l<q[i].l)
    		{
    			if(nxt[l]) update(nxt[l],-1);
    			if(nxt[nxt[l]]) update(nxt[nxt[l]],1);
    			l++;
    		}
    		q[i].ans=query(q[i].r)-query(q[i].l-1);
    	}
    	sort(q+1,q+m+1,cmp2);
    	for(RR int i=1;i<=m;i++)
    	{
    		printf("%d
    ",q[i].ans);
    	}
    	return 0;
    }
    

    小结:对于这种询问种类的题要是可以离线的话就这个做法,要是强制在线就得上树套树了。

  • 相关阅读:
    LeetCode-求最长回文子序列
    C++四种类型转换总结
    kmp算法分析和C++实现
    把二叉树打印成多行
    考研数据结构笔记—堆排序
    天勤考研数据结构笔记—栈的C语言实现
    合并两个排序的链表递归和非递归C++实现
    二叉树的线索化
    单链表的基本操作实现
    OpenFaceswap 入门教程(3): 软件参数篇!
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9557259.html
Copyright © 2011-2022 走看看