洛谷7月月赛题解(2020)

洛谷7月月赛题解

一.前言

​ 丑话说在前面,我只写了前三个的题解(因为有人告诉我第四题没有价值!!)

二.可持久化动态仙人掌的直径问题

​ 标题党,广大OIer看了直呼内行!真就签到题呗。反正就是把幂魔改成开根向下取个整。看代码吧。

int main(){
	cin>>n>>m;
	cout<<(int)pow(n,1.00/m);
	return 0;
}

三.混凝土数学

​ 混,混凝土??(擦汗),哎呀不就等腰三角形吗,分类讨论一手等腰和等边,选取 1~2*len-1 的边进行一下组合运算,就像我这样的蒟蒻才会放到桶里做,dalao们都是直接排一手序然后二分查找……不说了上代码

const int mod=998244353;
int n,maxx,x;
long long sum[200005],a[200005];
long long ans;
int main(){
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>x;
		a[x]++;
		maxx=max(maxx,x);
	}
	for(int i=1;i<=maxx;++i)sum[i]=(sum[i-1]+a[i])%mod;
	for(int i=1;i<=maxx;++i){
		if(a[i]>=3)ans=(ans+(1LL*(a[i]*(a[i]-1)/2)*(a[i]-2))/3%mod)%mod;
		if(a[i]>=2){
			long long u=(sum[min(maxx,2*i-1)]-a[i]+mod)%mod;
			ans=(ans+((1LL*a[i]*(a[i]-1)/2%mod)*u)%mod)%mod;
		}
	}
	cout<<ans%mod;
	return 0;
}

四.论如何玩转 Excel 表格

​ 首先,明确几个基本点。

  • 旋转180度之后,在同一列的两个点还是在同一列。
  • 旋转的本质是左上换右下与左下换右上
  • 对于任意一个数字,它在表格中的可移动轨迹呈'W'形

知道这些点后,那么可以快速地判断出无解的情况:1.该在同一列的不在同一列 2.不在'W'轨迹上,可以用奇偶判别法。

判断完无解后,由于表格是由两个'W'上下插在一起,同一列也是一一对应,所以只把其中的一条'W'拿出来给它拉直就好。于是我们得到两个不包含重复元素的序列,求由这个序列转换到另一个序列的最小操作数(操作为将相邻的两个数交换)。

​ 其实到这里有一点冒泡排序的意思在里面,如果变成转换为升序直接逆序对就完事了。

​ 关于转换成升序,很显然数值并不是升序的,但是下标是。假设原序列为 a ,目标序列为 b,那么对于一个 \(a_i\),b中有且只有一个(与上文的不包含重复元素相照应)与它值相同的 \(b_j\)\(b_j\) 的下标 j 放到 i 的位置去,构成一个新序列 c ,那么c 转化为升序就是答案,即 c 的逆序对数。(这里有点绕,但是很重要)

​ 这里我逆序对采用权值树状数组,从后往前扫描,单点修改和求和(不会的我稍微讲一下,由于从后往前,所以保证了在一个新点加入的时候树状数组内的全是下标比他大的,于是求个和sum(a[i]-1)就得出了下标大但是数值小的个数,最后把 a[i] 对应的改为1)

然后代码里面有个比较绕的指针……凑合着看,以及有两个辅助的函数(魔改成define了,一个是知道列号给出W中的位置,一个是知道W中的位置给出列号)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<fstream>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define fz(x) (x>n?x-n:x)
#define fx(x) (x%2?x:x+n)
const int MAXN=2*1e6+5;
int n,a[MAXN],b[MAXN],to[MAXN],c[MAXN];
int read(){
	char ch=getchar();
	int res=0,f=1;
	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
	return res*f;
}
long long ans;
void add(int x){
	for(;x<=n;x+=lowbit(x))c[x]++;
}
int get(int x){
	int res=0;
	for(;x;x-=lowbit(x))res+=c[x];
	return res;
}
int main(){
	n=read();
	for(int i=1;i<=n*2;++i)to[(a[i]=read())]=i;
	for(int i=1;i<=n*2;++i)b[i]=read();
	for(int i=1;i<=n;++i){
		if(to[b[i]]<=n&&(i-fz(to[b[i]]))%2==1){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]>n&&(i-fz(to[b[i]]))%2==0){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]>n&&a[to[b[i]]-n]!=b[i+n]){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]<=n&&a[to[b[i]]+n]!=b[i+n]){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
	}
	for(int i=n+1;i<=2*n;++i){
		if(to[b[i]]<=n&&(i-n-fz(to[b[i]]))%2==0){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]>n&&(i-n-fz(to[b[i]]))%2==1){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]>n&&a[to[b[i]]-n]!=b[i-n]){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
		if(to[b[i]]<=n&&a[to[b[i]]+n]!=b[i-n]){
			cout<<"dldsgay!!1"<<endl;
			return 0;
		}
	}
	for(int i=n;i>=1;--i){
		int u=b[fx(i)];
		ans+=get(fz(to[u])-1);
		add(fz(to[u]));
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/clockwhite/p/13382108.html