18.11.7绍一模拟赛
T1排序
题意:
给定一个快排,有四种键值选取方法:选区间左边端点,选区间右边端点,选区间终点,选一个随机数。
若为随机数,给定随机数种子以及生成方式。
现在要求用\(1~N\)构成一个数据卡掉这个快排。
分析:
题意是真毒瘤……
当了一回毒瘤出题人……
不过还是挺简单的,我们发现要把快排卡成\(O(n^2)\),每次取到的键值是最小值或者最大值就可以了。
我们先把数组赋值,使\(a[i]=i\)。
然后每次区间缩小一个长度,把取键值的位置和左端点交换。
最后\(a\)数组记录的\(a[i]\)就是每个元素原来的位置。
我们只要让\(b[a[i]]=i\),最后的\(b\)数组就可以卡掉这个快读了。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#define ull unsigned long long
#define ll long long
#define file "sort"
using namespace std;
ull read(){
char c;ull num,f=1;
while(c=getchar(),!isdigit(c))if(c=='-')f=-1;num=c-'0';
while(c=getchar(), isdigit(c))num=num*10+c-'0';
return f*num;
}
int n,type,cnt,a[100009];
int b[100009];
ull seed;
int rnd(int l,int r){
seed=seed*48271%2147483647;
return seed%(r-l+1)+l;
}
int main()
{
freopen(file".in","r",stdin);
freopen(file".out","w",stdout);
n=read();type=read();cnt=read();
if(type==1||type==2){
for(int i=1;i<=n;i++)
printf("%d ",i);
printf("\n");
}
else if(type==3){
for(int i=1;i<=n;i++)a[i]=i;
for(int i=1;i<=n;i++)
swap(a[i],a[(n+i)/2]);
for(int i=1;i<=n;i++)
b[a[i]]=i;
for(int i=1;i<=n;i++)
printf("%d ",b[i]);
printf("\n");
}else if(type==4){
seed=read();
for(int i=1;i<=n;i++)a[i]=i;
for(int l=1;l<=n;l++)
swap(a[l],a[rnd(l,n)]);
for(int i=1;i<=n;i++)
b[a[i]]=i;
for(int i=1;i<=n;i++)
printf("%d ",b[i]);
printf("\n");
}
return 0;
}
T2图
题意
见 CF979E Kuro and Topological Parity
分析
神仙dp。。
不会写滚粗
T3公交
题意
见CF983E NN country
或BZOJ2167: 公交车站
分析
LCA神仙题。。
不会写滚粗