zoukankan      html  css  js  c++  java
  • 「JOISC 2014 Day1」 历史研究

    「JOISC 2014 Day1」 历史研究

    Solution

    子任务2

    暴力,用(cnt)记录每种权值出现次数。

    子任务3

    这不是一个尺取吗...

    然后用multiset维护当前的区间,动态加,删点即可。

    子任务4

    目前可以支持在(o(log(n) ))的时间里动态加,删单点了。

    容易想到莫队。

    直接用multiset维护复杂度(o(n sqrt n log(n)))。(一脸不可过)

    稍微优化一下

    ​ 若使用cnt记录的话,是没法很好的删点的。

    ​ 对于目前要处理的块([l,r]),询问右端点单调,没有删点的操作,需要删点操作的是左端点的块内移动。

    ​ 事实上,左端点的块内移动可以直接改为加入需要用到的点。

    (cnt)统计(r+1)以后的点 ,cnt本身维护一个最大值MAX。加入块内的点 时,MAX不变,维护一个ANS。

    ​ 这样就不需要删点了(加入的 块内的点 回滚一下即可)。

    最终复杂度(o(n sqrt n))

    Code

    #include<bits/stdc++.h>
    #define rep(q,a,b) for(int q=a,q##_end_=b;q<=q##_end_;++q)
    #define dep(q,a,b) for(int q=a,q##_end_=b;q>=q##_end_;--q)
    #define mem(a,b) memset(a,b,sizeof a )
    #define debug(a) cerr<<#a<<' '<<a<<"___"<<endl
    using namespace std;
    void in(int &r) {
    	static char c;
    	r=0;
    	while(c=getchar(),!isdigit(c));
    	do r=(r<<1)+(r<<3)+(c^48);
    	while(c=getchar(),isdigit(c));
    }
    const int mn=100005;
    int val[mn],mid[mn],n,Q;
    int cnt[mn];
    namespace something_only_for_fc{
    	void solve(){
    		int l,r;
    		while(Q--){
    			in(l),in(r);
    			long long Max=0;
    			rep(q,l,r)++cnt[val[q]];
    			rep(q,l,r)Max=max(Max,1LL*cnt[val[q]]*mid[val[q]]);
    			rep(q,l,r)--cnt[val[q]];
    			printf("%lld
    ",Max);
    		}
    	}
    }
    struct node{
    	int l,r,id;
    	bool operator <(const node &A)const{
    		return l==A.l?r<A.r:l<A.l;
    	}
    }qr[mn];
    long long ans[mn];
    namespace something_value_25pts{
    	multiset<long long> have_val;
    	multiset<long long>::iterator it;
    	void remove(long long v){
    		it=have_val.find(v);
    		if(it!=have_val.end())have_val.erase(it);
    	}
    	long long Max(){
    		it=have_val.end(),--it;
    		return (*it);
    	}
    	void solve(){
    		int now=1;
    		int l=1;
    		for(int r=1;r<=n;++r){
    			if(cnt[val[r]])remove(1LL*cnt[val[r]]*mid[val[r]]);
    			++cnt[val[r]];
    			have_val.insert(1LL*cnt[val[r]]*mid[val[r]]);
    			if(now<=Q&&r==qr[now].r){
    				while(l<qr[now].l){
    					remove(1LL*cnt[val[l]]*mid[val[l]]);
    					--cnt[val[l]];
    					if(cnt[val[l]])have_val.insert(1LL*cnt[val[l]]*mid[val[l]]);
    					++l;
    				}
    				ans[qr[now].id]=Max();
    				++now;
    			}
    		}
    		rep(q,1,Q)printf("%lld
    ",ans[q]);
    	}
    }
    bool pts_25_check(){
    	rep(q,2,Q)if(qr[q].l==qr[q-1].l)return 0;
    	return 1;
    }
    namespace something_just_for_fun{
    	
    	vector<node> son[400];
    	long long Max,an;
    	void add(int v){
    		++cnt[v];
    		Max=max(Max,1LL*cnt[v]*mid[v]);
    	}
    	void mid_add(int v){
    		++cnt[v];
    		an=max(an,1LL*cnt[v]*mid[v]);
    	}
    	
    	int now_r;
    	void move(int to){
    		rep(q,now_r+1,to)add(val[q]);
    		now_r=to;
    	}
    	bool cmp(node a,node b){
    		return a.r<b.r;
    	}
    	void get(int x,int now){
    		if(!son[x].size())return;
    		now_r=now,Max=0;
    		rep(q,1,n)cnt[q]=0;
    		sort(son[x].begin(),son[x].end(),cmp);
    		rep(q,0,(int)son[x].size()-1){
    			if(son[x][q].r<=now){
    				an=0;
    				rep(w,son[x][q].l,son[x][q].r)mid_add(val[w]);
    				rep(w,son[x][q].l,son[x][q].r)--cnt[val[w]];
    			}else{
    				move(son[x][q].r);
    				an=Max;
    				rep(w,son[x][q].l,now)mid_add(val[w]);
    				rep(w,son[x][q].l,now)--cnt[val[w]];
    			}
    			ans[son[x][q].id]=an;
    		}
    	}
    	void solve(){
    		int K=sqrt(n)+1;
    		int lim=n/K;
    		rep(q,1,Q)son[qr[q].l/K].push_back(qr[q]);
    		rep(q,0,lim)get(q,min(n,(q+1)*K-1));
    		rep(q,1,Q)printf("%lld
    ",ans[q]);
    	}
    }
    int main(){
    	freopen("history.in","r",stdin);
    	freopen("history.out","w",stdout);
    	in(n),in(Q);
    	rep(q,1,n)in(val[q]),mid[q]=val[q];
    	sort(mid+1,mid+n+1);
    	rep(q,1,n)val[q]=lower_bound(mid+1,mid+n+1,val[q])-mid;
    	if(n<=5000&&Q<=5000)something_only_for_fc::solve();
    	else{
    		rep(q,1,Q)in(qr[q].l),in(qr[q].r),qr[q].id=q;
    		sort(qr+1,qr+Q+1);
    		if(pts_25_check())something_value_25pts::solve();
    		else something_just_for_fun::solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    vue项目引用less报错
    vue dev配置代理会报404
    为什么需要用到消息队列
    理解kafka消费者
    WebSocket和long poll、ajax轮询的区别
    数据库开发——MySQL——慢查询优化
    数据库开发——MySQL——索引原理
    数据库开发——MySQL——函数与流程控制
    数据库开发——MySQL——内置功能
    数据库开发——MySQL——pymysql模块
  • 原文地址:https://www.cnblogs.com/klauralee/p/11283605.html
Copyright © 2011-2022 走看看