zoukankan      html  css  js  c++  java
  • NOIP2020 退役记

    NOIP2020 退役记

    把原来写的东西全删了。毕竟留下了不少遗憾,也让我自己失望了吧。

    12:30 想到 T3 怎么做,写完后发现第二个样例过不去,也就爆零了。

    晚上回家理顺了一遍思路,写了半个小时不到就写完并在 oitiku 上 AC 了。我刷了不少 AGC 和 CF 的构造题,原本只是准备省选和 NOI 写的,结果 NOIP 考到了。我以为我能暴切 T3 考到省队线,结果被 T3 送退役了。

    估分 (80sim 100+84sim 100+0+60sim 80=224sim 280)。不过应该省选还是会去的,但是翻盘的可能性不大了。

    不过我也努力过了,这次的失误也是我想题较慢的缘故。若是把这道 T3 放到省选或 NOI 上,我感觉自己能现场写出来的。太遗憾了,实在是太遗憾了。

    要是 T3 一点都不会做该多好,这样我就可以安心退役了。我真的心有不甘啊啊啊啊啊啊。

    唉,在绝望中给人希望是一件多么残酷的事情。

    T3 做法:

    考虑分治,将颜色编号 (le mid)(>mid) 分为两个集合。这样问题转化为只用若干个长度为 (m)(01) 串,将要求每个串全部 (0/1)

    接着考虑两个串 (S,T)。可以知道,(cnt_{S,0/1}+cnt_{T,0/1}) 总有一个 (ge m)。那么,我们可以通过如下构造,得到一个串全部 (0/1)

    设空串为 (now)。取 (S,T) 的后 (lfloor frac m2 floor) 位,放到 (now) 中。如果是 (0) 放到 (S)(1) 放到 (T),那么可以得到一个长为 (lfloor frac m2 floor) 的串全部 (0/1)。若是 (S),再将 (S) 全部放到 (now)。此时 (S) 为空串,(T) 没有性质,(now)(lfloor frac m2 floor) 位相等。此处用了 (3m) 次操作。

    对于串 (now)(T),我们取 (now) 的后 (lceil frac m2 ceil) 位,(T) 的后 (lfloor frac m2 floor) 位,执行类似刚才的操作。此时 (now) 的后 (lceil frac m2 ceil) 位相等。此处用了 (2m) 次操作。

    现在讨论 (now)(lfloor frac m2 floor) 位和后 (lceil frac m2 ceil) 位是否相等。若相等,那么我们已经构造了出来。否则,将 (now) 的后 (lceil frac m2 ceil) 位放到 (S),然后对 (T) 执行刚才的过程。如果是 (0) 放到 (S)(1) 放到 (now)。这样 (S/now) 一定有一个串符合条件,用了 (frac 32m) 次操作。

    上界大概是 (O(F(n) imes frac {13}{2}m))(F(n)=sum (len_{rt}-1))(rtin) 长度为 (n) 的线段树。(F(50)=237),可以放心写,不怎么卡常数。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=55;
    const int maxa=820005;
    int n,m,x_[maxa],y_[maxa],sz,now;
    vector<int> g[maxn];
    inline void add(int x,int y)
    {
    	x_[++sz]=x,y_[sz]=y;
    	g[y].push_back(g[x].back());
    	g[x].pop_back();
    }
    void solve(int l,int r,vector<int> &id)
    {
    	if(id.size()==1) return;
    	int mid=(l+r)>>1;
    	vector<int> A,B; A.clear(),B.clear();
    	while(!id.empty())
    	{
    		int s=id.back(); id.pop_back();
    		int t=id.back(); id.pop_back();
    		// s, t -> now
    		for(int i=0;i<m/2;i++) add(s,now),add(t,now);
    		int pa=0,pb=0;
    		for(int i=0;i<g[now].size();i++)
    			if(g[now][i]<=mid) pa++;
    			else pb++;
    		int op1=(pa>=m/2)?0:1;
    		while(!g[now].empty())
    		{
    			if(((op1==0 && g[now].back()<=mid) || (op1==1 && g[now].back()>mid)) && g[s].size()<m) add(now,s);
    			else add(now,t);
    		}
    		for(int i=0;i<m;i++) add(s,now);
    		for(int i=0;i<m/2;i++) add(t,s);
    		for(int i=0;i<(m+1)/2;i++) add(now,s);
    		int qa=0,qb=0;
    		for(int i=0;i<g[s].size();i++)
    			if(g[s][i]<=mid) qa++;
    			else qb++;
    		int op2=(qa>=(m+1)/2)?0:1;
    		while(!g[s].empty())
    		{
    			if(((op2==0 && g[s].back()<=mid) || (op2==1 && g[s].back()>mid)) && g[now].size()<m) add(s,now);
    			else add(s,t);
    		}
    		if((g[now][0]<=mid)==(g[now].back()<=mid))
    		{
    			if(g[now].back()<=mid) A.push_back(now);
    			else B.push_back(now);
    			if(id.empty())
    			{
    				if(g[t].back()<=mid) A.push_back(t);
    				else B.push_back(t);
    			}
    			else id.push_back(t);
    			now=s;
    		}
    		else
    		{
    			// op1 -> now, op2 -> s
    			for(int i=0;i<(m+1)/2;i++) add(now,s);
    			int x=0,y=0;
    			for(int i=0;i<g[t].size();i++)
    				if(g[t][i]<=mid) x++;
    				else y++;
    			if(op2==0)
    			{
    				if(x+g[s].size()>=m)
    				{
    					while(!g[t].empty())
    					{
    						if(g[t].back()<=mid && g[s].size()<m) add(t,s);
    						else add(t,now);
    					}
    					A.push_back(s);
    					if(id.empty())
    					{
    						if(g[now].back()<=mid) A.push_back(now);
    						else B.push_back(now);
    					}
    					else id.push_back(now);
    					now=t;
    				}
    				else
    				{
    					while(!g[t].empty())
    					{
    						if(g[t].back()>mid && g[now].size()<m) add(t,now);
    						else add(t,s);
    					}
    					B.push_back(now);
    					if(id.empty())
    					{
    						if(g[s].back()<=mid) A.push_back(s);
    						else B.push_back(s);
    					}
    					else id.push_back(s);
    					now=t;
    				}
    			}
    			else
    			{
    				if(y+g[s].size()>=m)
    				{
    					while(!g[t].empty())
    					{
    						if(g[t].back()>mid && g[s].size()<m) add(t,s);
    						else add(t,now);
    					}
    					B.push_back(s);
    					if(id.empty())
    					{
    						if(g[now].back()<=mid) A.push_back(now);
    						else B.push_back(now);
    					}
    					else id.push_back(now);
    					now=t;
    				}
    				else
    				{
    					while(!g[t].empty())
    					{
    						if(g[t].back()<=mid && g[now].size()<m) add(t,now);
    						else add(t,s);
    					}
    					A.push_back(now);
    					if(id.empty())
    					{
    						if(g[s].back()<=mid) A.push_back(s);
    						else B.push_back(s);
    					}
    					else id.push_back(s);
    					now=t;
    				}
    			}
    		}
    	}
    	solve(l,mid,A),solve(mid+1,r,B);
    }
    int main()
    {
    	freopen("ball.in","r",stdin);
    	freopen("ball.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    		{
    			int x; scanf("%d",&x);
    			g[i].push_back(x);
    		}
    	vector<int> id; id.clear();
    	for(int i=1;i<=n;i++) id.push_back(i);
    	now=n+1,solve(1,n,id);
    	printf("%d
    ",sz);
    	for(int i=1;i<=sz;i++)
    		printf("%d %d
    ",x_[i],y_[i]);
    	return 0;
    }
    
  • 相关阅读:
    以下文件中的行尾不一致。要将行尾标准化吗
    用户 NT AUTHORITYNETWORK SERVICE 登录失败
    sql server 2008 不允许保存更改,您所做的更改要求删除并重新创建以下表 的解决办法
    附加数据库对于服务器失败(Microsoft.SqlServer.Smo),无法升级数据库,因为它是只读的,或者具有只读文件
    IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法
    HTTP 错误 404.2
    vs智能提示突然消失的解决办法 (vs2008 vs2010 vs2012 智能提示)
    Visual Studio 常用快捷键
    403.14-Forbidden Web 服务器被配置为不列出此目录的内容及Login on failed for "IIS APPPOOLASP.NET v4.0"问题
    短信轰炸PC版
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/14090813.html
Copyright © 2011-2022 走看看