2018 Chinese Multi-University Training, Nanjing U Contest(多校第八场)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018 Chinese Multi-University Training, Nanjing U Contest(多校第八场)相关的知识,希望对你有一定的参考价值。
文章目录
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[p−1]>=q时,那么第 p p p个苹果其实没有被选中,此时需要找到 [ p + 1 , n ] [p+1,n] [p+1,n]第一个大于 p r e [ p − 1 ] pre[p-1] pre[p−1]的 h l a s h_{las} hlas
答案为 a n s [ p − 1 ] + s u f [ l a s ] ans[p-1]+suf[las] ans[p−1]+suf[las]
②.当 p r e [ p − 1 ] < q pre[p-1]<q pre[p−1]<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[p−1]+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有何区别