首页 > 其他分享 >Summer Training 2023 Mini Comp 1 (Experts)

Summer Training 2023 Mini Comp 1 (Experts)

时间:2023-07-24 17:14:45浏览次数:50  
标签:Summer Training 颜色 Mini int 询问 whi Subtask maxn

Summer Training 2023 Mini Comp 1 (Experts)

2338 Carnival - PCOI Online Judge (pcoij8.ddns.net)

题目大意

交互题,n个人穿着衣服,共有c种颜色,每一次可以询问一些人穿的衣服有多少种不同的颜色,最多可以询问3500次,请确定每个人穿的衣服是什么颜色

做法

第一眼可以看出来答案的上界是\(n*(n-1)/2\),就是两两询问衣服颜色是否相同。

考虑到3500的询问次数,很容易可以猜到对于每一个人,我们大约可以询问\(logn\)次

于是我们可以考虑从左到右逐个确定

我们假设前面的n个都已经确定了,我们现在考虑确定第n+1个

我们设前面n个一共有a种不同的种类,这个我们可以很容易的记录下来我们可以直接选择将第n+1个与前面的n个进行比对,时间复杂度显然为\(n^2\)

我们考虑进行优化

如果我们直接询问1到n+1的颜色,只会出现两种答案,a或a+1

如果返回为a+1,那么第n+1个就是新的颜色

如果返回为a就是说明和前面的颜色重合

我们询问1-mid,加上n+1的颜色,如果是比1-mid的颜色多,但是1-n+1的颜色数又为a,那么说明n+1的颜色与mid+1到n的相同

这样我们就可以不断确定l-r区间,最终确定到一个数

考虑到这一道题的n比较小,对于询问过的区间,我们可以记录下来,采用记忆化

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=155;
int cnt=0,q[maxn],c,n,f[maxn],A[maxn][maxn];
int guess(int l,int r,int now){
	if(l==r&&now==-1)return 1;
	if(now==-1&&A[l][r])return A[l][r];
	int whi=(now==-1)?1:0;
	cout<<r-l+1 +1-whi<<" ";
	for(int i=l;i<=r;i++){
		cout<<q[i]<<" ";
	}
	if(!whi)
	cout<<now;
	cout<<endl;
	cin>>c;
	if(now==-1)A[l][r]=c;
	return c;
}
int main(){
	cin>>n;
	f[1]=1;
	q[1]=1;
	cnt=1;
	for(int i=2;i<=n;i++){
		if(guess(1,cnt,i)==cnt+1){
			f[i]=++cnt;
			q[cnt]=i;
			continue;
		}
		int l=1,r=cnt;
		while(l<r){
			int mid=(l+r)/2;
			if(guess(1,mid,i)!=guess(1,mid,-1))l=mid+1;
			else r=mid;
		}
		f[i]=l;
	}
	cout<<0;
	for(int i=1;i<=n;i++)cout<<" "<<f[i];
	cout<<endl;
	
	return 0;
}

2339 Toys "R" Us - PCOI Online Judge (pcoij8.ddns.net)

题目大意

询问\([l,r]\)中第一个没有出现的正整数

做法

一眼莫队,对于寻找第一个没出现的正整数,我们考虑用set查询

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int cnt[maxn],a[maxn],ans[maxn];
set<int>Set;
int n,m,l,size;
struct node{
	int x,y,id;
}q[maxn];
bool cmp(node x,node y){
	if(x.x/size==y.x/size)return x.y<y.y;
	return x.x/size<y.x/size;
}
void update(int now,int whi){
	if(whi==1){
		cnt[a[now]]++;
		if(cnt[a[now]]==1){
			Set.erase(a[now]);
		}
	}
	else{
		cnt[a[now]]--;
		if(!cnt[a[now]])
			Set.insert(a[now]);
	}
}
int main(){
	for(int i=1;i<=100001;i++)Set.insert(i);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d",&q[i].x,&q[i].y);
		q[i].id=i;
	}
	size=sqrt(m);
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++){
		int ql=q[i].x,qr=q[i].y;
		while(r<qr)update(++r,1);
		while(r>qr)update(r--,-1);
		while(l>ql)update(--l,1);
		while(l<ql)update(l++,-1);
		ans[q[i].id]=*Set.begin();
	}
	for(int i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	
	
	return 0;
}

2340 Xor-Paths - PCOI Online Judge (pcoij8.ddns.net)

题目大意

走路径,路径上异或和为k的方案数

做法

一开始以为暴力的时间复杂度是\(2^{20}\),交完之后发现T掉了,才发现复杂度是\({2^{40}}\)

但也不难,一眼折半搜索

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=25;
int n,m,K,a[maxn][maxn],ans=0;
map<int,int>mp1[maxn],mp2[maxn];
bool check(int x,int y){
	return 1<=x&&x<=n&&1<=y&&y<=m;
}
void dfs1(int x,int y,int k){
	if(!check(x,y))return ;
	k=(k^a[x][y]);
	if(x+y==m+1){
		mp1[x][k]++;
		return ;
	}
	dfs1(x+1,y,k);
	dfs1(x,y+1,k);
	return ;
}
void dfs2(int x,int y,int k){
	if(!check(x,y))return ;
	k=(k^a[x][y]);
	if(x+y==m+1){
		k^=a[x][y];
		mp2[x][k]++;
		return ;
	}
	dfs2(x-1,y,k);
	dfs2(x,y-1,k);
	return ;
}
signed main(){
	cin>>n>>m>>K;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	dfs1(1,1,0);
	dfs2(n,m,0);
	for(int whi=1;whi<=n;whi++)
	for(map<int,int>::iterator it=mp1[whi].begin();it!=mp1[whi].end();it++){
		int num1=it->first,cnt1=it->second;
		int num2=(K^num1),cnt2=mp2[whi][num2];
		ans+=cnt1*cnt2;
	}
	cout<<ans<<endl;
	return 0;
}

2343 Make Divisible - PCOI Online Judge (pcoij8.ddns.net)

题目大意

找到正整数\(X,Y\),使得\(A+X\mid B+Y\),且\(X+Y\)最小

做法

明显发现有\(Y\le A\),所以答案上界为\(X+Y\le A\)

Subtask 1,2:枚举\(X\),然后我们可以\(O(1)\)算出\(Y\),,直接算出答案

Subtask 4:明显\(A-B\)

Subtask 3:分类讨论,

若\(A,B\le 10^5\),则为Subtask 1;

若\(A> 10^5,B\le 10^5\),则为Subtask 4;

Subtask 5:

\[\begin{aligned} &设正整数k,满足k(A+X)=B+Y\\ &有kA+kX=B+Y\\ &就有kX=B-kA+Y\\ &我们枚举k,如果B-kA<0,则X=0,Y=kA-B\\ &如果B-kA>0,则X=\lceil\frac{B-kA}{k}\rceil时最好,同时算出Y\\ &随着k增大,B-kA越来越小,小于0之后kA-B越来越大,答案越来越劣\\ &大约要枚举\frac{B}{A}次,最多枚举10^5次\\ \end{aligned} \]

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int t,a,b;
signed main(){
    cin>>t;
    while(t--){
    	int minn=1e9+7;
        cin>>a>>b;
        if(a>=b){
        cout <<a-b<<endl;
        continue;
        }
        if (a>1e5&&b>1e5){
        	for(int k=1;k<=1e5;k++){
        		if(k*a>b)minn=min(minn,k*a-b);
        		else{
		          	int B1=b-k*a;
		          	if(B1<0)minn=min(minn,-B1);
		          	int X=ceil(B1*1.0/k),Y=k*X-B1;
		          	minn=min(minn,X+Y);
	          	}		
		  }
        }
        else 
        for(int i =0;i <=min(a,minn);i ++){
            minn =min (minn,i +(a+i-b%(a+i))%(a+i));
            int A1=a+i,B1= b+(a+i-b%(a+i))%(a+i),K=B1/A1,N=A1+B1;
		}
		cout<<minn<<endl;

    }
    return 0;
}

总结

100+28+100+33

T1开始就基本想到了二分,但是因为第一次写交互题,不熟,花的时间比较长

然后开T2,第一时间想到主席树,但因为太长不想打,先跳过

T3开始看错范围,直接爆搜,发现时间复杂度算错,后面想到折半搜索,但在细节上的处理花了比较长的时间

T4数学题,先把subtask 4秒掉,然后打了个暴力,直接枚举X+Y的和然后判断正确性

考场上连上界\(X+Y\le A\)都没有想到,更别说看出subtask 3 的特殊性了

然后看回T2,看subtask4一下就知道题解是莫队,但没有学过,于是考虑立方暴力,然后用优先队列优化为\(O(n^2logn)\)

依然不想写主席树,也没发现subtask 3 可以用前缀和做

最后跑去T4,啥都没想出来

只能说还是不太会拿部分分

标签:Summer,Training,颜色,Mini,int,询问,whi,Subtask,maxn
From: https://www.cnblogs.com/Ayaka-T/p/17577735.html

相关文章

  • vmware安装minimal centos报错/etc/rc5.d/s99local : line:25 : eject : command not
    1.vmware安装minimalcentos报错/etc/rc5.d/s99local:line:25:eject:commandnotfoundhttp://www.centoscn.com/image-text/install/2015/1130/6459.html 2.vmwareworkstation上安装centoshttp://www.linuxidc.com/Linux/2016-05/131701.htm 3.虚拟机可以ping通主机和8.8......
  • centos7 安装 minio RELEASE.2021-06-17
    1、下载执行包wgethttps://dl.min.io/server/minio/release/linux-amd64/archive/minio.RELEASE.2021-06-17T00-10-46Z2、创建数据、日志文件夹mkdir-p/data/project/minio/data/mkdir-p/data/project/minio/log/touch/data/project/minio/log/minio.log3、授......
  • minipc使用frp端口映射
    参考官网文档使用frp配置内网访问宝塔面板部署frp内网穿透FRP内网穿透实战使用场景之前购买的云服务器硬盘比较小,很快满了,加上希望将数据放本地服务器。故此某宝买了minipc,安装了Ubuntuserver。以下使用腾讯云轻量服务器centos安装frps,本地minipc系统Ubuntu安装frpc,记录......
  • minio性能测试
    minio性能测试minio的使用前期使用了s3fs但是想验证一下性能相关,所以使用今天简单验证了一下,其实也可以使用一下fio但是s3fs是对象存储没有修改只有上传,所以感觉还是使用dd更加好一些.dd性能测试脚本-读取rm-rf/tmp/cache/*echo3>/proc/sys/vm/drop_cach......
  • [解题报告][CF1007E]Mini Metro
    Statement传送门有\(n\)个车站,从\(1\)到\(n\)编号,车站\(i\)初始有\(a_i\)个人。在每个小时结束的前几分钟,车站\(i\)会新增\(b_i\)个人。玩家有无限辆容量为\(k\)的火车。玩家在每个小时的中间(也就是\(\mathrm{30min,1h30min,2h30min...}\))可以让任意......
  • 2023.07.21 SMU Summer 2023 Contest Round 5
    2023.07.21SMUSummer2023ContestRound5A.PointsinSegments给n个,1~m的子集,求1~n中所有没在这些子集中出现过的数字把子集区间合并为集合s,输出1~n中没有在s中出现过的数#include"bits/stdc++.h"usingnamespacestd;typedefpair<int,int>PII;intn,m;vector<P......
  • MINIO配置TLS访问
    服务端证书生成opensslgenrsa-outca.key2048opensslreq-x509-new-nodes-keyca.key-subj"/CN=*.*.*.*"-days365-outca.crtopensslgenrsa-outserver.key2048opensslreq-new-nodes-keyserver.key-subj"/CN=*.*.*.*"-outserver.cs......
  • SMU Summer 2023 Contest Round 5
    SMUSummer2023ContestRound5A.PointsinSegments\(\mathcal{O}(n\timesm)\)做法数据范围小,直接把每次的\(l-r\)跑一遍标记一下,最后跑一遍循环统计哪些没有被标记的并且输出就好了#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signed......
  • [LeetCode] 2268. Minimum Number of Keypresses
    Youhaveakeypadwith 9 buttons,numberedfrom 1 to 9,eachmappedtolowercaseEnglishletters.Youcanchoosewhichcharacterseachbuttonismatchedtoaslongas:All26lowercaseEnglishlettersaremappedto.Eachcharacterismappedtoby exact......
  • X-Camp 2023 Summer Training 做题泛记
    由于我懒,本Blog只记录暑期集训的难题&趣题,当然大部分难题我都不会做。\(\textbf{D1T2}\)很奇妙的一题,不过我不会。可以看xhgua的博客。\(\textbf{D5T3}\)模拟赛放Ynoi,兄弟。\(\textbf{D5T3.1Description}\)实现一个数据结构,要求实现三个操作:在图中将两个点连边;回......