• BZOJ4241历史研究——回滚莫队


    题目描述

    IOI国历史研究的第一人——JOI教授,最近获得了一份被认为是古代IOI国的住民写下的日记。JOI教授为了通过这份日记来研究古代IOI国的生活,开始着手调查日记中记载的事件。
    日记中记录了连续N天发生的时间,大约每天发生一件。
    事件有种类之分。第i天(1<=i<=N)发生的事件的种类用一个整数Xi表示,Xi越大,事件的规模就越大。
    JOI教授决定用如下的方法分析这些日记:
    1. 选择日记中连续的一些天作为分析的时间段
    2. 事件种类t的重要度为t*(这段时间内重要度为t的事件数)
    3. 计算出所有事件种类的重要度,输出其中的最大值
    现在你被要求制作一个帮助教授分析的程序,每次给出分析的区间,你需要输出重要度的最大值。

    输入

    第一行两个空格分隔的整数N和Q,表示日记一共记录了N天,询问有Q次。
    接下来一行N个空格分隔的整数X1...XN,Xi表示第i天发生的事件的种类
    接下来Q行,第i行(1<=i<=Q)有两个空格分隔整数Ai和Bi,表示第i次询问的区间为[Ai,Bi]。

    输出

    输出Q行,第i行(1<=i<=Q)一个整数,表示第i次询问的最大重要度

    样例输入

    5 5
    9 8 7 8 9
    1 2
    3 4
    4 4
    1 4
    2 4

    样例输出

    9
    8
    8
    16
    16

    提示

    1<=N<=10^5
    1<=Q<=10^5
    1<=Xi<=10^9 (1<=i<=N)
     
    这道题要求的是最大值,显然不满足可减行,不能用普通莫队来解决。
    在普通莫队排序时,是按照左端点所属块为第一关键字、右端点为第二关键字来排序的,那么我们将左端点属于同一块的询问一起处理。
    对于左端点都属于同一块的询问,右端点排序后是单调递增的,所以对于这些询问中的每个询问,我们都固定左指针为下一块的第一个点不动,每次只移动右指针。
    当右指针不动后,再将询问的左端点到左指针部分加入计算,得出这个询问的答案后再将这部分删掉。因为每次左指针移动都不大于$sqrt{n}$,所以总时间复杂度还是$O(nsqrt{n})$。
    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<bitset>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int block;
    int n,m;
    struct lty
    {
    	int l,r,id;
    }q[100010];
    int a[200010];
    int h[200010];
    ll ans[100010];
    ll cnt[200010];
    ll res,mx;
    int b[100010];
    bool cmp(lty x,lty y)
    {
    	return b[x.l]==b[y.l]?x.r<y.r:x.l<y.l;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	block=sqrt(n);
    	for(int i=1;i<=n;i++)
    	{
    		b[i]=(i-1)/block+1;
    	}
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		h[i]=a[i];
    	}
    	sort(h+1,h+1+n);
    	int num=unique(h+1,h+1+n)-h-1;
    	for(int i=1;i<=n;i++)
    	{
    		a[i]=lower_bound(h+1,h+1+num,a[i])-h;
    	}
    	for(int i=1;i<=m;i++)
    	{
    		scanf("%d%d",&q[i].l,&q[i].r);
    		q[i].id=i;
    	}
    	sort(q+1,q+1+m,cmp);
    	int R=0,L=0;
    	for(int i=1;i<=m;i++)
    	{
    		if(b[q[i].l]!=L)
    		{
    			memset(cnt,0,sizeof(cnt));
    			R=(L=b[q[i].l])*block+1;
    			mx=cnt[a[R]]=h[a[R]];
    		}
    		if(b[q[i].l]==b[q[i].r])
    		{
    			cnt[a[R]]-=h[a[R]];
    			res=0;
    			for(int j=q[i].l;j<=q[i].r;j++)
    			{
    				res=max(res,cnt[a[j]]+=h[a[j]]);
    			}
    			ans[q[i].id]=res;
    			for(int j=q[i].l;j<=q[i].r;j++)
    			{
    				cnt[a[j]]-=h[a[j]];
    			}
    			cnt[a[R]]+=h[a[R]];
    		}
    		else
    		{
    			while(R<q[i].r)
    			{
    				++R;
    				mx=max(mx,cnt[a[R]]+=h[a[R]]);
    			}
    			ans[q[i].id]=mx;
    			for(int j=b[q[i].l]*block;j>=q[i].l;j--)
    			{
    				ans[q[i].id]=max(ans[q[i].id],cnt[a[j]]+=h[a[j]]);
    			}
    			for(int j=b[q[i].l]*block;j>=q[i].l;j--)
    			{
    				cnt[a[j]]-=h[a[j]];
    			}
    		}
    	}
    	for(int i=1;i<=m;i++)
    	{
    		printf("%lld
    ",ans[i]);
    	}
    }
  • 相关阅读:
    Spring-boot-admin功能说明
    Spring Boot Admin 的使用 2
    Spring Boot Admin的使用
    windows下的Nodejs及npm的安装、常用命令,Nodejs开发环境配置
    dataTables-使用详细说明整理
    JQuery Datatables Dom 和 Language 参数详细说明
    深入SpringBoot:自定义PropertySourceLoader
    java complier compliance level问题引发的思考
    在线代码格式化工具
    Gradle中的buildScript代码块
  • 原文地址:https://www.cnblogs.com/Khada-Jhin/p/10655061.html
Copyright © 2020-2023  润新知