【原创】2019.10.24模拟赛 嘟嘟噜/天才绅士少女助手克里斯蒂娜/凤凰院凶真

说在前面

神仙OJ!

嘟嘟噜

mayuri.cpp/in/out
Time Limit: 2s
Memory Limit: 512MB
开启 -O2 优化
开启无限栈

1.1 Description

由于众所周知的原因, 冈部一直欠真由理一串香蕉.
为了封上真由理的嘴, 冈部承诺只要真由理回答出这个问题, 就给她买一车的香蕉:
一开始有 n 个人围成一个圈, 从 1 开始顺时针报数, 报出 m 的人被机关处决. 然后下一个人再从 1 开始报数, 直到只剩下一个人.
红莉栖: “这不就是约瑟夫问题吗…”
伦太郎: “助手你给我闭嘴!”
真由理虽然已经晕头转向了, 但听到有一车的香蕉, 两眼便放出了光芒. “那个呢, 真由氏很想要一车子的香蕉呢. 如果可以帮帮我的话, 我可以把一些香蕉分给你哟, 诶
嘿嘿. 拜托你啦.”

1.2 Input Format

第一行一个整数 T, 表示数据组数.
接下来 T 行, 每行两个整数 n, m.

1.3 Output Format

对于每组数据, 输出一行一个整数, 表示幸存者的编号.

1.4 Sample

1.4.1 Input

5
4 6
2 8
2 9
8 8
7 9

1.4.2 Output

3
1
2
4
7

1.5 Constraints

在这里插入图片描述

1.6 分析

经典的约瑟夫问题

1.7 代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
inline void Read(ll &p)
{
	p=0;
	char c=getchar();
	while(c<'0' || c>'9') c=getchar();
	while(c>='0' && c<='9')
		p=p*10+c-'0',c=getchar();
}

ll T,n,m,ans;

int main()
{
	freopen("mayuri.in","r",stdin);
	freopen("mayuri.out","w",stdout);
	
	Read(T);
	while(T--)
	{
		Read(n),Read(m),ans=0;
		for(ll i=1;i<=n;i++)
		{
			ll k=min((i-ans)/m-1,n-i-1);
			if(k>0 && k<n) ans+=k*m,i+=k;
			(ans+=m)%=i;
		}
		printf("%lld\n",ans+1);
	}
}

天才绅士少女助手克里斯蒂娜

在这里插入图片描述在这里插入图片描述在这里插入图片描述总感觉那个助手崩掉了……

2.6 分析

瞪了15min发现是 叉 积 ! ! ! ! ! \LARGE \LARGE 叉积!\raisebox{0.625cm}{\LARGE!}\raisebox{1.25cm}{\LARGE!}\raisebox{2.5cm}{\LARGE!}\raisebox{5cm}{\LARGE!}

叉积就是 x 1 y 2 − x 2 y 1 x_1y_2-x_2y_1 x1y2x2y1
叉积的平方就是 x 1 2 y 2 2 + x 2 2 y 1 2 − 2 x 1 y 1 x 2 y 2 x_1^2y_2^2+x_2^2y_1^2-2x_1y_1x_2y_2 x12y22+x22y122x1y1x2y2
于是 a n s = ∑ i = l r ∑ j = i + 1 r ( x i 2 y j 2 + x j 2 y i 2 − 2 x i y i x j y j ) = ∑ i = l r ∑ j = i + 1 r x i 2 y j 2 + ∑ i = l r ∑ j = i + 1 r x j 2 y i 2 − ∑ i = l r ∑ j = i + 1 r 2 x i y i x j y j = ∑ i = l r ∑ j = l r [ i ! = j ] × x i 2 y j 2 − ∑ i = l r ∑ j = l r [ i ! = j ] × x i y i x j y j = ∑ i = l r x i 2 ( ∑ j = l r y j 2 − y i 2 ) − ( ∑ i = l r x i y i ( ∑ j = l r x j y j − x i y i ) ) = ∑ i = l r x i 2 ∑ j = l r y j 2 − ∑ i = l r x i 2 y i 2 − ( ∑ i = l r x i y i ∑ j = l r x j y j − ∑ i = l r x i 2 y i 2 ) = ∑ i = l r x i 2 × ∑ i = l r y i 2 − ( ∑ i = l r x i y i ) 2 ans = \sum \limits_{i=l}^{r} \sum \limits_{j=i+1}^r (x_i^2y_j^2+x_j^2y_i^2-2x_iy_ix_jy_j) \\ = \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r x_i^2y_j^2 + \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r x_j^2y_i^2 - \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r 2x_iy_ix_jy_j \\ = \sum \limits_{i=l}^r \sum \limits_{j=l}^r [i!=j]\times x_i^2y_j^2 - \sum \limits_{i=l}^r \sum \limits_{j=l}^r [i!=j]\times x_iy_ix_jy_j \\ =\sum \limits_{i=l}^r x_i^2 (\sum \limits_{j=l}^r y_j^2 -y_i^2) - (\sum \limits_{i=l}^r x_iy_i (\sum \limits_{j=l}^r x_jy_j - x_iy_i)) \\ = \sum \limits_{i=l}^r x_i^2 \sum \limits_{j=l}^r y_j^2 - \sum \limits_{i=l}^r x_i^2y_i^2 - (\sum \limits_{i=l}^r x_iy_i \sum \limits_{j=l}^r x_jy_j - \sum \limits_{i=l}^r x_i^2 y_i^2) \\ = \sum \limits_{i=l}^r x_i^2\times \sum \limits_{i=l}^ry_i^2 - (\sum \limits_{i=l}^r x_iy_i)^2 ans=i=lrj=i+1r(xi2yj2+xj2yi22xiyixjyj)=i=lrj=i+1rxi2yj2+i=lrj=i+1rxj2yi2i=lrj=i+1r2xiyixjyj=i=lrj=lr[i!=j]×xi2yj2i=lrj=lr[i!=j]×xiyixjyj=i=lrxi2(j=lryj2yi2)(i=lrxiyi(j=lrxjyjxiyi))=i=lrxi2j=lryj2i=lrxi2yi2(i=lrxiyij=lrxjyji=lrxi2yi2)=i=lrxi2×i=lryi2(i=lrxiyi)2

我太懒了,连KATEX都是copy来的

2.7 代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

//typedef long long int;
inline void Read(int &p)
{
	p=0;
	char c=getchar();
	while(c<'0' || c>'9') c=getchar();
	while(c>='0' && c<='9')
		p=p*10+c-'0',c=getchar();
}

const int MAXN=1002030,mod=20170927;
int n,m,opt,u,v,w,x[MAXN],y[MAXN];
inline int lowbit(int x){return x&(-x);}
struct BIT
{
	int bit[MAXN];
	inline void update(int pos,int del){while(pos<=n) (bit[pos]+=del)%=mod,pos+=lowbit(pos);}
	inline int getsum(int pos){int ans=0; while(pos) (ans+=bit[pos])%=mod,pos-=lowbit(pos); return ans;}
	inline int query(int lef,int rig){return getsum(rig)-getsum(lef-1);}
}arr[3];

int main()
{
	freopen("kurisu.in","r",stdin);
	freopen("kurisu.out","w",stdout);
	Read(n),Read(m);
	for(int i=1;i<=n;i++) Read(x[i]),Read(y[i]),arr[0].update(i,1ll*x[i]*x[i]%mod),arr[1].update(i,1ll*y[i]*y[i]%mod),arr[2].update(i,1ll*x[i]*y[i]%mod);
	while(m--)
	{
		Read(opt);
		if(opt==1) Read(u),Read(v),Read(w),arr[0].update(u,1ll*v*v%mod-1ll*x[u]*x[u]%mod),arr[1].update(u,1ll*w*w%mod-1ll*y[u]*y[u]%mod),arr[2].update(u,1ll*v*w%mod-1ll*x[u]*y[u]%mod),x[u]=v,y[u]=w;
		else Read(u),Read(v),w=arr[2].query(u,v),printf("%d\n",((1ll*arr[0].query(u,v)*arr[1].query(u,v)-1ll*w*w)%mod+mod)%mod);
	}
}

2.8 说在后面

我之前全文用的long long,T惨了,2.020s望洋兴叹。然后换回int以后就能节省1s左右。

在这里插入图片描述

凤凰院凶真

凤凰院凶真
okarin.cpp/in/out
Time Limit: 1s
Memory Limit: 512MB
不开启 -O2 优化
Special Judge

3.1 Description

α 世界线.
凤凰院凶真创立了反抗 SERN 统治的组织 “瓦尔基里”. 为了脱离 α 线, 他需要制作一个世界线变动率测量仪.
测量一个世界线相对于另一个世界线的变动率, 实质上就是要求出这两个世界线的最长公共合法事件序列.
一个世界线的事件逻辑序列是一个正整数序列, 第 k 个数表示第 k 个事件发生的时间.
对于一个世界线, 一个合法的事件序列是事件逻辑序列的一个子序列, 满足时间严格递增.
现在, 对于两个不同的世间线 α, β, 求出最长的一个事件序列, 满足这个序列在 α, β 世界线中均是合法的. 这个序列也就是之前提到过的最长公共合法事件序列.

3.2 Input Format

第一行一个整数 n, 表示 α 世界线的事件个数.
第二行 n 个整数 a1, a2, …, an, 表示 α 世界线的事件逻辑序列.
第三行一个整数 m, 表示 β 世界线的事件个数.
第四行 m 个整数 b1, b2, …, bm, 表示 β 世界线的事件逻辑序列.

3.3 Output Format

第一行一个整数 k, 表示最长公共合法事件序列的长度.
第二行 k 个整数, 表示最长公共合法事件序列. 如果有多解, 输出任意一个.

3.4 Sample

3.4.1 Input

5
1 4 2 5 1
4
1 1 2 4

3.4.2 Output

2
1 4
5

3.5 Constraints

无论执迷过去
还是叹息未来
皆是不准有丝毫误算的必然
所以本题将捆绑测试. 也就是说, 只有你通过一个子任务内的所有测试点, 才能获得该子任务的全部分数, 否则得 0 分.
在这里插入图片描述

3.6 分析

最长公共上升子序列板子题。
虽然我也没敲过这板子。

3.7代码

#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
inline void Read(int &p)
{
	p=0;
	char c=getchar();
	while(c<'0' || c>'9') c=getchar();
	while(c>='0' && c<='9')
		p=p*10+c-'0',c=getchar();
}

const int MAXN=5024;
stack<int>S;
int n,m,arr[MAXN],brr[MAXN],dp[MAXN][MAXN],pre[MAXN][MAXN],pos=1;

int main()
{
	freopen("okarin.in","r",stdin);
	freopen("okarin.out","w",stdout);	
	Read(n); for(int i=1;i<=n;i++) Read(arr[i]);
	Read(m); for(int i=1;i<=m;i++) Read(brr[i]);
	
	memset(pre,-1,sizeof pre);
	for(int i=1;i<=n;++i)
	{
		int v=0,k=0;
		for(int j=1;j<=m;++j)
		{
			dp[i][j]=dp[i-1][j];
			if(brr[j]<arr[i] && v<dp[i-1][j]) v=dp[i-1][j],k=j;
			if(arr[i]==brr[j]) dp[i][j]=v+1,pre[i][j]=k;
		}
	}
	
	for(int i=1;i<=n;++i) if(dp[n][pos]<dp[n][i]) pos=i;
	printf("%d\n",dp[n][pos]);
	if(dp[n][pos]!=0)
	{
		for(int i=n;i>=1;i--) if(pre[i][pos]!=-1) S.push(arr[i]),pos=pre[i][pos];
		while(!S.empty()) printf("%d ",S.top()),S.pop();
		puts("");
    }
}

说在后面

在这里插入图片描述
想找个乔瑟夫的图我容易吗?

(龙舌兰?)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值