zoukankan      html  css  js  c++  java
  • AT1219 歴史の研究

    附带权值的类区间众数问题?不是很好策啊

    发现题目没有强制在线,而且也只有询问操作,那么可以考虑莫队

    但是这里的莫队有一个很显著的特征,插入的时候很好维护答案,但是删除的时候不好回退

    那么有没有什么办法可以让莫队避免删除呢,当然是有的,而且这可以解决一大类类似问题

    考虑类似于一般莫队的分块操作,我们再排序时以左端点所在块为第一关键字,右端点为第二关键字

    那么我们可以根据左端点所在块分别处理这些询问

    首先如果左右端点在同一块内,那么很简单,直接暴力统计完了直接删光光就好了,这是(O(sqrt n))

    如果不是呢?由于此时的右端点是递增的,我们维护一个指针不停地往右边插入数即可,对于每一块的复杂度不会超过(O(n)),由于一共只有(sqrt n)块,所以总体还是(O(nsqrt n))

    可是这个时候左端点只是在同一块里并不是不变的。但是这部分的长度最多也是(sqrt n)啊,再不济和暴力一样做了在删了就好了吗,一共(n)个询问所以最多也是(O(nsqrt n))

    所以这样的话复杂度就被压到了(O(nsqrt n)),顺便提一下这种神奇的莫队方法叫做回滚莫队,不过还是比较好理解的

    CODE

    #include<cstdio>
    #include<cctype>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define RI register int
    #define CI const int&
    #define Tp template <typename T>
    using namespace std;
    typedef long long LL;
    const int N=100005;
    int blk[N]; struct ques
    {
    	int l,r,id;
    	inline ques(CI L=0,CI R=0,CI Id=0)
    	{
    		l=L; r=R; id=Id;
    	}
    	inline friend bool operator <(const ques& A,const ques& B)
    	{
    		return blk[A.l]<blk[B.l]||(blk[A.l]==blk[B.l]&&A.r<B.r);
    	}
    }q[N]; int n,m,a[N],rst[N],num,now,size,bkt[N],tbkt[N]; LL ans[N],ret;
    class FileInputOutput
    {
    	private:
    		static const int S=1<<21;
    		#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
    		#define pc(ch) (Ftop<S?Fout[Ftop++]=ch:(fwrite(Fout,1,S,stdout),Fout[(Ftop=0)++]=ch))
    		char Fin[S],Fout[S],*A,*B; int pt[25],Ftop;
    	public:
    		Tp inline void read(T& x)
    		{
    			x=0; char ch; while (!isdigit(ch=tc()));
    			while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
    		}
    		Tp inline void write(T x)
    		{
    			if (!x) return (void)(pc('0'),pc('
    ')); RI ptop=0;
    			while (x) pt[++ptop]=x%10,x/=10; while (ptop) pc(pt[ptop--]+48); pc('
    ');
    		}
    		inline void Fend(void)
    		{
    			fwrite(Fout,1,Ftop,stdout);
    		}
    		#undef tc
    		#undef pc
    }F;
    inline int min(CI a,CI b)
    {
    	return a<b?a:b;
    }
    Tp inline void maxer(T& x,const T& y)
    {
    	if (y>x) x=y;
    }
    inline LL calc(CI l,CI r,LL ret=0)
    {
    	RI i; for (i=l;i<=r;++i) tbkt[a[i]]=0; for (i=l;i<=r;++i)
    	++tbkt[a[i]],maxer(ret,1LL*tbkt[a[i]]*rst[a[i]]); return ret;
    }
    inline void add(CI now)
    {
    	++bkt[a[now]]; maxer(ret,1LL*bkt[a[now]]*rst[a[now]]);
    }
    inline void solve(CI id)
    {
    	int qr=min(id*size,n),pr=qr; RI i; memset(bkt,0,sizeof(bkt));
    	for (ret=0;blk[q[now].l]==id;++now)
    	{
    		if (blk[q[now].l]==blk[q[now].r]) { ans[q[now].id]=calc(q[now].l,q[now].r); continue; }
    		while (pr<q[now].r) add(++pr); LL t=ret; for (i=q[now].l;i<=qr;++i) add(i);
    		ans[q[now].id]=ret; for (i=q[now].l;i<=qr;++i) --bkt[a[i]]; ret=t;
    	}
    }
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	RI i; for (F.read(n),F.read(m),i=1;i<=n;++i) F.read(a[i]),rst[i]=a[i];
    	sort(rst+1,rst+n+1); num=unique(rst+1,rst+n+1)-rst-1; size=(int)sqrt(n);
    	for (i=1;i<=n;++i) blk[i]=(i-1)/size+1,a[i]=lower_bound(rst+1,rst+num+1,a[i])-rst;
    	for (i=1;i<=m;++i) F.read(q[i].l),F.read(q[i].r),q[i].id=i;
    	for (sort(q+1,q+m+1),now=i=1;i<=blk[n];++i) solve(i);
    	for (i=1;i<=m;++i) F.write(ans[i]); return F.Fend(),0;
    }
    
  • 相关阅读:
    Petya and Countryside
    大数A+B
    python-requests正则
    python-UnicodeDecodeError: 'gbk' codec can't decode byte 0xa8 in position 157: illegal multibyte sequence
    python-mysql数据迁移
    python-flask框架路由
    python-flask框架基础
    MYSQL-内外自连接-判断函数
    MYSQL-分组查询-where和having的区别
    mysql增删
  • 原文地址:https://www.cnblogs.com/cjjsb/p/10385708.html
Copyright © 2011-2022 走看看