2018 Chinese Multi-University Training, Nanjing U Contest(多校第八场)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 Chinese Multi-University Training, Nanjing U Contest(多校第八场)相关的知识,希望对你有一定的参考价值。

LINK

E - Magic Square(签到,模拟)

没什么好说的,模拟转转转就好了,自认为我写的还是比较简便的.

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int t,n;
char a[101][101];
void rotate(int x,int y,int num)
{
	for(int i=1;i<=num;i++)
	{
		char q = a[x][y], w = a[x][y+1], e = a[x+1][y+1], r = a[x+1][y];
		a[x][y] = r, a[x][y+1] = q, a[x+1][y] = e, a[x+1][y+1] = w;
	}
}
int main()
{
	cin >> t;
	while( t-- )
	{
		cin >> n;
		for(int i=1;i<=3;i++)	cin >> ( a[i]+1 );
		while( n-- )
		{
			string s; cin >> s;
			int type = ( s[1]=='C' )?1:3;//C就是顺时针转1次,否则顺时针转三次 
			if( s[0]=='1' )	rotate( 1,1,type );
			else if( s[0]=='2' )	rotate( 1,2,type );
			else if( s[0]=='3' )	rotate( 2,1,type );
			else	rotate( 2,2,type );
		}
		for(int i=1;i<=3;i++)	cout << ( a[i]+1 ) << endl;
	}
}

J. Taotao Picks Apples(二分,ST表)

题意

给定一个数组 h h h,其中 h i h_i hi表示第 i i i个苹果的高度.

首先第一个苹果必选,然后选择第 i i i个苹果当且仅当 h i h_i hi大于之前选的所有苹果

现在给出 m m m个独立的询问,每次给定 p , q p,q p,q,问若把 h p h_p hp改成 q q q,可以拿到几个苹果?


做法

预处理 p r e [ i ] pre[i] pre[i]表示在原始序列中 [ 1 , i ] [1,i] [1,i]拿到苹果的最大高度, a n s [ i ] ans[i] ans[i]表示拿到的数量

这个 O ( n ) O(n) O(n)扫一遍就好了

还需要处理 s u f [ i ] suf[i] suf[i]表示如果第 i i i个苹果被拿走,在 [ i , n ] [i,n] [i,n]区间能拿走几个苹果

转移为 s u f [ i ] = s u f [ l a s ] + 1 suf[i]=suf[las]+1 suf[i]=suf[las]+1

其中 l a s > = i & & h l a s > h i las>=i\\&\\&h_{las}>h_i las>=i&&hlas>hi且满足 l a s las las是索引最小的

这个简单,我们可以在 [ i + 1 , n ] [i+1,n] [i+1,n]二分一个 m i d mid mid,每次询问 [ i + 1 , m i d ] [i+1,mid] [i+1,mid]的最大值是否大于 h i h_i hi即可

这样就能得到最小索引的 l a s las las,使用 S T ST ST表处理区间最大值可以在 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))处理 s u f suf suf数组

于是对于每个询问,分两种情况.

①.当 p r e [ p − 1 ] > = q pre[p-1]>=q pre[p1]>=q时,那么第 p p p个苹果其实没有被选中,此时需要找到 [ p + 1 , n ] [p+1,n] [p+1,n]第一个大于 p r e [ p − 1 ] pre[p-1] pre[p1] h l a s h_{las} hlas

答案为 a n s [ p − 1 ] + s u f [ l a s ] ans[p-1]+suf[las] ans[p1]+suf[las]

②.当 p r e [ p − 1 ] < q pre[p-1]<q pre[p1]<q时,那么第 p p p个苹果被选中,此时需要找到 [ p + 1 , n ] [p+1,n] [p+1,n]第一个大于 q q q h l a s h_{las} hlas

答案为 a n s [ p − 1 ] + s u f [ l a s ] + 1 ans[p-1]+suf[las]+1 ans[p1]+suf[las]+1

时间复杂度为 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int T,n,m,h[maxn],p,q,pre[maxn],suf[maxn],ans[maxn],mx[maxn][22],lg[maxn];
int getmx(int l,int r)
{
	int k = lg[r-l+1];
	return max( mx[l][k],mx[r-(1<<k)+1][k] );
}
int getsuf(int now,int zhi)
{
	int l = now, r = n, ans = -1;
	while( r>=l )
	{
		int mid = l+r>>1;
		if( getmx(now,mid)>zhi )	r = mid-1, ans = mid;
		else	l = mid+1;
	}
	return ans;
}
int main()
{
	ios::sync_with_stdio( false );
	cin.tie( 0 ); cout.tie( 0 );
	for(int i=2;i<=200000;i++)	lg[i] = lg[i>>1]+1;
	cin >> T;
	while( T-- )
	{
		cin >> n >> m;
		for(int i=1;i<=n;i++)	cin >> h[i],mx[i][0] = h[i];
		for(int i=1;i<=20;i++)
		for(int j=1;j+(1<<i)-1<=n;j++)
			mx[j][i] = max( mx[j][i-1],mx[j+(1<<(i-1))][i-1] );
		for(int i=1;i<=n;i++)
		{
			if( h[i]>pre[i-1] )	pre[i] = h[i],ans[i] = ans[i-1]+1;
			else	pre[i] = pre[i-1], ans[i] = ans[i-1];
		}
		for(int i=n;i>=1;i--)
		{
			int hou = getsuf( i+1,h[i] );
			if( hou==-1 )	suf[i] = 1;
			else	suf[i] = suf[hou]+1;
		}
		while( m-- )
		{
			cin >> p >> q;
			if( pre[p-1]>=q )
			{
				int res = ans[p-1];
				int hou = getsuf( p+1,pre[p-1] );
				if( hou==-1 )	cout << res << endl;
				else	cout << res+suf[hou] << endl;
			}
			以上是关于2018 Chinese Multi-University Training, Nanjing U Contest(多校第八场)的主要内容,如果未能解决你的问题,请参考以下文章

The 2018 ACM-ICPC Chinese Collegiate Programming Contest Take Your Seat

2018-11-06 Visual Studio Code插件-英汉词典初版发布

speak in Chinese/speak Chinese有何区别

2018-12-10vscode的配置

COLLATE CHINESE_PRC_CI_AS_WS 的含义

Chinese remainder theorem