返回上一页

【比赛】国庆のsurprise

下发文件和题解

前置闲话

今天是国庆节,这个时间吧,我也是见过头一年学校不放假的(可能仅HE). 前年 6 天,去年 3 天,今年 0. 估计明年可能放 -3.

但是不过学长给了个惊喜,再次亮相题目. 说是最近看我们做的题目有点,想给我们送点温暖,结果……

az
#   用  户  名   Rubyonly is always here Su_Zipei is always here Kaiser_Kell is always here Pl_er is always here 总分
1
lxhcr 75
01:04:38
60
03:26:17
100
02:27:27
5
03:58:02
240
03:58:02
2
ceredora 10
03:57:53
60
03:35:09
100
02:46:04
0
03:59:38
170
03:59:38
3
Chen_jr 30
02:09:42
50
02:56:49
70
03:37:44
5
03:57:45
155
03:57:45
3
Muel_imj 0
03:59:42
100
02:20:47
55
03:51:28
155
03:59:42
5
chino 5
03:53:42
100
02:39:56
40
03:47:35
145
03:53:42
5
bikuhiku 95
03:35:30
0
03:24:42
50
02:38:18
0
03:56:55
145
03:56:55
7
Broken_Eclipse 30
01:06:30
80
03:33:21
30
03:43:34
0
03:51:10
140
03:51:10
8
Eakang 30
00:47:34
80
02:26:10
25
02:58:01
135
02:58:01
8
caster 80
02:42:12
55
03:54:56
135
03:54:56
8
joke3579 0
03:57:43
60
01:42:21
70
02:59:03
5
03:40:09
135
03:57:43
11
wenqizhi1125 30
03:04:39
60
02:12:56
35
01:03:32
125
03:04:39
11
hxq 50
01:18:25
75
02:39:31
0
03:58:09
125
03:58:09
13
abhwolxq 50
01:24:09
70
02:21:24
120
02:21:24
13
L 30
02:30:44
60
03:36:39
30
02:47:39
120
03:36:39
13
Houraisan_Kaguya 5
03:57:18
70
02:20:36
45
03:49:58
0
03:52:11
120
03:57:18
16
HT_walnut 60
02:35:16
50
01:37:25
5
03:56:18
115
03:56:18
17
wangruixue 60
02:24:52
50
03:43:25
110
03:43:25
18
1Liu 30
00:35:12
50
01:28:36
25
02:53:29
0
03:31:10
105
03:31:10
18
LovelessDress 30
02:22:58
30
03:36:07
35
01:37:36
10
02:06:22
105
03:36:07
18
smtwy 30
03:57:56
50
03:24:24
25
03:23:59
105
03:57:56
18
zasdcn 5
01:39:27
80
03:07:14
20
03:59:57
0
03:26:34
105
03:59:57
22
Jersan 30
02:55:20
0
03:08:09
70
03:40:28
0
03:46:27
100
03:46:27
22
ice_cup 100
02:54:51
0
01:27:58
0
02:13:36
0
03:47:07
100
03:47:07
22
lyin 100
02:08:53
0
03:17:00
0
03:57:27
0
03:59:18
100
03:59:18
25
crs_line 50
03:18:16
45
03:58:29
95
03:58:29
26
La_Pluma 0
02:51:25
60
01:52:42
30
03:10:45
0
03:16:20
90
03:16:20
26
Starlight 60
03:43:48
30
02:41:38
90
03:43:48
26
Clover_BY 5
02:12:27
50
01:52:31
25
03:53:10
10
03:22:18
90
03:53:10
26
sadom 30
02:48:01
30
03:54:59
30
03:02:21
0
03:56:20
90
03:56:20
26
morgan 0
03:45:49
80
03:38:02
10
03:58:56
90
03:58:56
31
Headto_CdqandAKNOIP 30
03:45:00
30
02:48:50
15
01:10:01
0
03:49:39
75
03:49:39
32
351238 10
03:56:41
30
03:23:57
25
03:52:05
0
03:51:32
65
03:56:41
33
sandom 30
03:03:07
20
01:12:47
10
01:56:11
0
03:40:30
60
03:40:30
33
Anakin 0
03:18:33
30
02:37:11
25
03:43:28
5
01:10:22
60
03:43:28
35
sandome 5
02:08:31
50
01:11:13
55
02:08:31
36
saridom 30
03:00:37
0
01:05:35
20
03:27:27
50
03:27:27
36
kiritokazuto 30
03:56:33
20
01:36:20
0
03:58:44
50
03:58:44
38
char_phi 30
02:15:08
10
03:33:43
40
03:33:43
39
WintersRain 30
01:46:14
5
03:34:46
0
03:07:58
35
03:34:46
39
gtm1514 30
03:50:16
5
03:52:44
35
03:52:44
39
IAKIOI 5
03:48:02
30
01:31:24
0
03:52:32
0
03:56:45
35
03:56:45
39
TSTYFST 0
03:57:41
30
02:13:24
5
03:09:31
0
03:43:51
35
03:57:41
43
2K22 0
03:55:05
30
03:55:15
0
03:55:38
30
03:55:38
44
zcyzcy 0
00:55:03
0
03:10:12
0
03:37:19
5
02:11:30
5
03:37:19

“这 T3 不是场切的题吗?”

题面放在下发文件和题解里了,请自取(密码请在 blog 内寻找,其实直接在题库里有,也没啥用)

A. Rubyonly is always here

首先,对于无解的判断:容易发现,经过若干次变换,这两个数的总和永远是一定的. 所以显然当 a + b ≠ c + d (mod p) 是肯定是无解的.

sum = a + b,由于数对 (a , b) 可以表示为 (a , sum - a),把每一个数都除以一个 sum,数对就可以表示为 (a , 1-a). 这里除的时候乘一个逆元即可(想一想,为什么?).

又可以发现,经过数次变换之后,这个数对一定会变成 (2a , 1 - 2a) 或者 (2a - 1 , 2 - 2a). 那么易知当 a 变为 c 时, b 一定变为 d.

那么就可以只看 a 的改变. 根据上面的那个式子,变换 k 次时最大会变为 2ka,最小会变为 2ka - (2k - 1). 这种变换最多只会进行 logp 次. 因此,枚举每一个 k,判断 c 是否在上述范围内即可.

点击查看代码
#include<bits/stdc++.h>
#define ll long long
#define rg register
#define sinline static inline
#define rll rg ll
#define maxn 100001
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
sinline ll read()
{
	rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
sinline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
ll p,q,lg,ans,a,b,sum,id,st,ed,c,d;
sinline ll ksm(rll a,rll b) { rll ans=1; a%=p; for(rll i=b;i;i>>=1) { if(i&1)ans=ans*a%p; a=a*a%p; } return ans; }

int main()
{
	p=read();lg=ceil(log2(p));q=read();while(q--)
	{
		a=read();b=read();c=read();d=read();sum=a+b;
		if(((ll)(a+b)%(ll)p)^((ll)(c+d)%(ll)p)) { puts("-1"); continue; }
		if(a==c&&b==d) { puts("0"); continue; }
		a=a*ksm(sum,p-2)%p,c=c*ksm(sum,p-2)%p;
		for(rll k=1;k<=lg;k++)
		{
			st=(a*(1<<k)-((1<<k)-1))%p;if(st<0) st+=p;
			ed=st+(1<<k)-1;
			if((st<=c&&c<=ed)||(st<=c+p&&c+p<=ed)||k==lg) { write(k);putn; break; }
		}
	}
	return 0;
}

B. Su_Zipei is always here

这题暴力加莫队能拿 80 分.

看到这个子任务:

对于另外 的数据,

首先想到的就是开一个 300 × n 的数组,记录个前缀和,每次暴力跑一遍这 300 个数.

这就启示了正解做法:

又是根号分治

对于出现的总次数小于 的颜色,其在每段区间里出现的次数也一定小于 次. 那么把整个序列进行分块,整块处理散块暴力,枚举一个数和前面所有相同颜色数的出现次数,记录产生的贡献.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define sinline static inline
#define rll rg ll
#define maxn 100001
#define mx 35
#define pll pair<ll,ll>
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
sinline ll read()
{
	rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
sinline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
struct node { ll a,b,id; };
ll n,q,l,r,bell,belr,mxl,mxr,k,op,sq,ans;
ll a[maxn];
ll cnt[mx+1][maxn],sum[mx+1][mx+1][maxn],tot[maxn];
int main()
{
	n=read(),q=read(),op=read(); sq=min((ll)sqrt(n),mx); for(rll i=1;i<=n;i++) a[i]=read();
	for(rll i=1;i<=sq;i++)
	{
		l=(i-1)*(n/sq)+1,r=i*(n/sq);if(r>n) r=n;
		for(rll j=1;j<=n;j++) cnt[i][j]=cnt[i-1][j]; for(rll j=l;j<=r;j++) cnt[i][a[j]]++;
	}
	for(rll i=1;i<=sq;i++) for(rll j=1;j<=sq;j++)
	{
		for(rll k=1;k<=n;k++) sum[i][j][cnt[j][k]-cnt[i-1][k]]++;
		for(rll k=1;k<=n;k++) sum[i][j][k]+=sum[i][j][k-1];
	}
	while(q--)
	{
		if((l=(read()+ans*op-1)%n+1)>(r=(read()+ans*op-1)%n+1)) swap(l,r); k=(read()+ans*op-1)%n+1;
		ans=0;bell=(l+(n/sq)-1)/(n/sq),belr=(r+(n/sq)-1)/(n/sq);
		if(belr-bell<=1)
		{
			for(rll i=l;i<=r;i++) tot[a[i]]++,ans+=tot[a[i]]==k;
			write(ans);putn; for(rll i=l;i<=r;i++) tot[a[i]]=0;continue;
		}
		mxl=bell*(n/sq),mxr=(belr-1)*(n/sq)+1;ans=sum[bell+1][belr-1][n]-sum[bell+1][belr-1][k-1];
		for(rll i=l;i<=mxl;i++) { tot[a[i]]++; ans+=tot[a[i]]+cnt[belr-1][a[i]]-cnt[bell][a[i]]==k; }
		for(rll i=mxr;i<=r;i++) { tot[a[i]]++; ans+=tot[a[i]]+cnt[belr-1][a[i]]-cnt[bell][a[i]]==k; }
		write(ans);putn; for(rll i=l;i<=mxl;i++) tot[a[i]]=0; for(rll i=mxr;i<=r;i++) tot[a[i]]=0;
	}
	return 0;
}

C. Kaiser_Kell is always here

这题想必已经不用多说,是一道数据结构大水题.

我赛时以为空间不够打了线段树又删了

第二问,见CSP-S模拟7自然数题目. 线段树更新操作相同,查询改一下即可.

第一问,让求区间 mexmex. 由下面的内容可以知道(我懒得打了):

把每个点的 mex 值记录一下,在更新线段树权值时也记录一下区间 mex. 查询时看第一个没有出现的数即可.

点击查看代码
#include<bits/stdc++.h>
#define ll int
#define rg register
#define sinline static inline
#define rll rg ll
#define maxn 1000001
#define pll pair<ll,ll>
#define put_ putchar(' ')
#define putn putchar('\n')
using namespace std;
sinline ll read()
{
	rll f=0,x=0;rg char ch=getchar();while(ch<'0'||ch>'9') f|=ch=='-',ch=getchar();
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^'0'),ch=getchar();return f?-x:x;
}
sinline void write(rll x) { if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10|'0'); }
struct node
{
	ll l,r,id;
	inline friend bool operator<(rg node a,rg node b) { if(a.l==b.l) return a.r<b.r; return a.l<b.l; }
}b[maxn];
struct tree
{
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
	ll v,mn,tag;
}t[maxn<<2];
ll n,q,a[maxn],mex[maxn],nx[maxn],pos[maxn],ans[maxn],num=1,mx=1;
bool fl[maxn],vis[maxn];
// __gnu_pbds::gp_hash_table<ll,ll> mp;
#define pushup(rt) t[rt].v=t[ls(rt)].v+t[rs(rt)].v,t[rt].mn=min(t[ls(rt)].mn,t[rs(rt)].mn)
sinline void pushdown(rll rt,rll l,rll r)
{
	if(t[rt].tag)
	{
		rll mid=(l+r)>>1; t[ls(rt)].v=t[rt].tag*(mid-l+1);t[rs(rt)].v=t[rt].tag*(r-mid);
		t[ls(rt)].mn=t[rs(rt)].mn=t[ls(rt)].tag=t[rs(rt)].tag=t[rt].tag; t[rt].tag=0;
	}
}
sinline void build(rll rt,rll l,rll r)
{
	if(l==r) { t[rt].v=t[rt].mn=mex[l]; return; }
	rll mid=(l+r)>>1;build(ls(rt),l,mid);build(rs(rt),mid+1,r);pushup(rt);
}
sinline void upd(rll rt,rll l,rll r,rll x,rll y,rll v)
{
	if(x<=l&&r<=y) { t[rt].v=v*(r-l+1); t[rt].mn=t[rt].tag=v; vis[t[rt].tag]=1; return; }
	pushdown(rt,l,r); rll mid=(l+r)>>1;
	if(x<=mid) upd(ls(rt),l,mid,x,y,v); if(y>mid) upd(rs(rt),mid+1,r,x,y,v); pushup(rt);
}
sinline ll queryv(rll rt,rll l,rll r,rll x,rll y)
{
	if(x<=l&&r<=y) return t[rt].v; pushdown(rt,l,r); rll mid=(l+r)>>1,ans=0;
	if(x<=mid) ans+=queryv(ls(rt),l,mid,x,y); if(y>mid) ans+=queryv(rs(rt),mid+1,r,x,y);
	return ans;
}
sinline ll querymn(rll rt,rll l,rll r,rll pos)
{
	if(l==r) return t[rt].mn; pushdown(rt,l,r); rll mid=(l+r)>>1;
	if(pos<=mid) return querymn(ls(rt),l,mid,pos); else return querymn(rs(rt),mid+1,r,pos);
}
int main()
{
	mex[0]=1; n=read(); for(rll i=1;i<=n;i++) a[i]=read(); q=read(); for(rll i=1;i<=q;i++) b[i]=(node){read(),read(),i}; sort(b+1,b+q+1);
	for(rll i=1;i<=n;i++) { fl[a[i]]=1; mex[i]=mex[i-1]; if(a[i]==mex[i]) while(fl[mex[i]]) mex[i]++; vis[mex[i]]=1; } memset(fl,0,sizeof(fl));
	build(1,1,n);// for(rll i=1;i<=n;i++) write(mex[i]),put_;
	for(rll i=1;i<=n;i++) pos[i]=n+1;
	for(rll i=n;i;i--) { /*if(!mp[a[i]]) nx[i]=n+1;else*/ nx[i]=pos[a[i]];pos[a[i]]=i; }
	// mp.clear();
	for(rll i=1,now=1,l,r,k;i<=n;i++)
	{
		while(b[num].l==i) ans[b[num].id]+=queryv(1,1,n,i,b[num].r)-queryv(1,1,n,i,b[num].r-1),num++;
		l=i;r=nx[i]-1;k=-1;
		while(l<r)
		{
			rll mid=(l+r)>>1;
			if(querymn(1,1,n,mid+1)>a[i]) k=mid+1,r=mid; else l=mid+1;// write(l);put_;write(r);putn;
		}
		if(k^-1) upd(1,1,n,k,nx[i]-1,a[i]);
	}
	while(vis[mx]) mx++;write(mx);putn;
	for(rll i=1;i<=q;i++) write(ans[i]),put_;
	return 0;
}

D. Pl_er is always here

暂咕……

posted @   1Liu  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界
点击右上角即可分享
微信分享提示