这些XJB算法的题竟然是小夏令营题想想就好可怕TAT(你萌不知道什么是XJB算法???)
讲道理这道题的标程虽然奇短无比但是想法还是蛮有启发意义的。。。我试着口胡一下原理QAQ
先考虑无元素重复的情况:
首先会得到N+1个序列的按字典序排列的最后一个值
对于每一个序列,为了表达方便,我们扯一个三元组
出来,注意到所有
组成的集合和
组成的集合一模一样(一个环上所有相邻元素的集合)。
而我们得到的序列就是将所有三元组
按照
双关键字排序之后输出的
序列。
注意到所有
组成的集合和
组成的集合一模一样,所以我们先把这个集合给弄出来,我们将得到的原序列复制一遍,由小到大排序后和原序列粘到一起再排一遍序(实现技巧见代码),至此我们弄出了按照
排序的数字对序列
,这也是按照
排序的数字对序列。
#前方有点难说清楚我尽量
设答案序列也就是原序列为
,设给出的序列为
首先我们在原序列中找到唯一的一个0的位置,假设它在给出的原序列中的位置是K(
),那么我们就知道
是序列
中的第K个元素。但是!我们已经得到了
序列,所以我们就可以得到
的值。
然后我们发现,如果我们再在原序列
中
的位置,一切找
的过程就和找
一模一样辣!!!
以上
至于有重复元素的情况。。。把双关键字排序改成带下标的三关键字稳定排序就可以辣!!!(我不知道为什么但原理应该相通)
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 200005
void _read(int &x)
{
x=0; char ch=getchar(); bool flag=false;
while(ch<'0' || ch>'9'){if(ch=='-')flag=true; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} if(flag)x=-x; return ;
}
int A[MAXN],B[MAXN],C[MAXN],Next[MAXN],ans[MAXN],N,M;
bool cmp(int x,int y)
{
if(A[x]!=A[y])return A[x]