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

    题目

    AT1219 歴史の研究

    分析

    回滚莫队板子。

    首先我们发现这个题可以离线,并且数据范围很小,还要维护和出现次数相关的信息,于是可以想到莫队。

    然后我们发现这个最大值答案直接莫队的话在撤销的时候不好维护,于是我们可以考虑回滚莫队。

    那么现在就很简单了,我们直接维护一下每个值的 (cnt) 数组,再拿一个变量来记录最大值即可,我们随时更新这个变量就行了。

    复杂度 (O(nsqrt{n}))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=2e5+5;
    #define ll long long
    int n,m,k;
    ll a[N],b[N],cnt[N],Ans[N];
    int cl,clear[N],bl[N],block,blo;
    struct Query{
    	int l,r,id;
    	Query(int l=0,int r=0,int id=0):l(l),r(r),id(id){}
    	inline bool operator < (const Query &B)const{return bl[l]!=bl[B.l]?bl[l]<bl[B.l]:r<B.r;}
    }Q[N];
    ll Cnt[N];
    ll Calc(int l,int r){
    	ll res=0;
    	for(int i=l;i<=r;i++) Cnt[a[i]]=0;
    	for(int i=l;i<=r;i++) Cnt[a[i]]++,res=max(res,Cnt[a[i]]*b[a[i]]);
    	return res;
    }
    signed main(){
    	read(n);read(m);
    	const int t=sqrt(n);
    	for(int i=1;i<=n;i++) read(a[i]),b[i]=a[i],bl[i]=(i-1)/t+1;
    	blo=bl[n];
    	sort(b+1,b+n+1);
    	int Id=unique(b+1,b+n+1)-b-1;
    	for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+Id+1,a[i])-b;
    	for(int i=1;i<=m;i++){
    		int l,r;read(l),read(r);
    		Q[i]=Query(l,r,i);
    	}
    	sort(Q+1,Q+m+1);
    	for(int i=1,j=1;j<=blo;j++){
    		int R=min(j*t,n),l=R+1,r=R;cl=0;
    		ll now=0;
    		for(;bl[Q[i].l]==j;i++){
    			if(bl[Q[i].r]==j){
    				Ans[Q[i].id]=Calc(Q[i].l,Q[i].r);
    				continue;
    			}
    			while(r<Q[i].r){
    				r++;
    				cnt[a[r]]++;clear[++cl]=a[r];
    				now=max(now,cnt[a[r]]*b[a[r]]);
    			}
    			ll tmp=now;
    			while(l>Q[i].l){
    				l--;
    				cnt[a[l]]++;
    				now=max(now,cnt[a[l]]*b[a[l]]);
    			}
    			Ans[Q[i].id]=now;
    			while(l<=R){
    				cnt[a[l]]--;
    				l++;
    			}
    			now=tmp;
    		} 
    		for(int k=1;k<=cl;k++) cnt[clear[k]]--;
    	}
    	for(int i=1;i<=m;i++) write(Ans[i]),putchar('
    ');
    	return 0;
    } 
    
  • 相关阅读:
    javascript
    javascript
    javascript
    easyui datagrid checkbox multiple columns have been done do
    combogrid获取多个字段的方法
    jquery显示、隐藏div的方法
    纠正jQuery获取radio选中值的写法
    comgrid获取多选值
    xheditor
    java向图片上写字,两个图片合并的方法
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14706370.html
Copyright © 2011-2022 走看看