• Codeforces Round #683 (Div. 2, by Meet IT) 题解&总结


    值得纪念。

    但以后不会再有了QAQ

    A

    其它的增高相当于自己降低。所以按顺序输出(1)(n)即可。

    (由于一开始看反了导致挂了一次……)

    B

    两点间随意找一条路径操作,路径中间的点没有影响,只会影响端点。

    全局找任意对数将其符号取反。贪心即可。

    C

    先从大到小排序,能选就选。由于要求的下界是上界的一半,从大往小选,不存在少选一个大的,多选几个小的才能满足的情况。

    (似乎不排序也能做)

    D

    朴素DP。直接设(f_{i,j}),也就是普通的LCS问题改点细节而已。

    E

    D到E花了1.5h,E到F1花了不到0.5h。我在干嘛……

    https://www.cnblogs.com/jz-597/p/13986661.html

    F

    显然全局众数也是最优区间的众数之一(否则考虑最优区间扩张的过程,必定存在一次局部众数和全局众数的出现次数相等)。

    找出全局众数,分别枚举每一个数,变成如下问题:全局众数出现的位置为(+1),这个数出现的位置为(-1),其它位置为(0),求最长的和为(0)的区间。

    第一档部分分直接开个桶来维护。时间(O(100n))。贴代码:

    using namespace std;
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 200005
    int n,m;
    int a[N];
    int s[N][101];
    int p[N];
    int buc[N*2];
    void upd(int &a,int b){
    	if (a==-1) a=b;
    }
    int main(){
    //	freopen("in.txt","r",stdin);
    	scanf("%d",&n);
    	for (int i=1;i<=n;++i){
    		scanf("%d",&a[i]);
    		memcpy(s[i],s[i-1],sizeof s[i]);
    		s[i][a[i]]++;
    	}
    	int id=1,mx=s[n][1];
    	for (int i=2;i<=100;++i)
    		if (s[n][i]>mx)
    			mx=s[n][i],id=i;
    		else if (s[n][i]==mx)
    			id=-1;
    	if (id==-1){
    		printf("%d
    ",n);
    		return 0;
    	}
    	p[0]=0;
    	for (int i=1;i<=n;++i)
    		if (a[i]==id)
    			p[++m]=i;
    	p[++m]=n+1;
    	memcpy(s[n+1],s[n],sizeof s[n]);
    	int ans=0;
    	for (int i=1;i<=100;++i){
    		if (i==id)
    			continue;
    		memset(buc,255,sizeof buc);
    		for (int j=0;j<=m;++j){
    //			if (j==3)
    //				j=3;
    //			printf("query(%d)
    ",s[p[j]][i]-j);
    			if (buc[s[p[j]][i]-j +N]!=-1)
    				ans=max(ans,p[j]-buc[s[p[j]][i]-j +N]-1);
    //			printf("upd(%d,%d)
    ",s[p[j]][i]-j-1,p[j]);
    			upd(buc[s[p[j]][i]-j-1 +N],p[j]);
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    

    对于第二档,题解做法:如果这个数的出现次数(|V|>sqrt n),那么用上述方法(O(n))做;否则,对于这个数的每个出现位置(V_i),提取出左右离它最近的全局众数,一共要做(O(|V|))个位置,每个位置要么是一个(-1)或一段(+1)。可以直接(O(|V|^2))。总时间(O(nsqrt n))

    其实也可以做到(O(nlg n))。用线段树维护区间的前缀最大值和最小值。当需要找一个值的的第一次出现位置的时候,由于每次只会(+1)(-1),是连续的,如果这个值在最小值最大值之间,就一定存在。那么在线段树上二分即可。

    都没写。


    感觉这次发挥比较好。

    原因大概有:

    1. 这次咖啡选择在晚餐后喝,比赛期间精神饱满,肾上腺素激增,上厕所时能感受到心跳,打题时感觉到右臂的动脉在动。(我不是在吹)。
    2. 这次题目比较适合我发挥,不像上次div2那样全场构造。
    3. 2:30的写题时间,第一次div2切了超过4题。
    4. 秒切了不知道为什么没什么人写的F1。

    当然了这次也存在一些败笔。在想题的时候(尤其是E题),绕了很长的弯子,中间想了个可能不靠谱的阴间做法,交了一遍自然挂了。感觉应该要更严谨一些,那种做法应该被ban掉的。

    div1我来啦!

  • 相关阅读:
    sqlmap基础使用(以sqli—labs第一关为例)
    IIS、Apache、Nginx日志记录的各个字段内容与含义
    建站+阿里云服务器上传个人制作网页
    SQL server 2005 在Windows server 2003上面的安装
    VMware里kali虚拟机的安装
    第三章web安全基础—http协议及burpsuite基本使用(brupsuite导入证书支持https访问)
    第三章web安全基础—互联网注册网站相关小知识
    第三章web安全基础—IIS发布dvbbs(动网论坛)及SQL2005问题解决
    根据现有目录批量创建文件夹
    PL/SQL通过存储过程为相同数据添加序号
  • 原文地址:https://www.cnblogs.com/jz-597/p/13987051.html
Copyright © 2020-2023  润新知