这些XJB算法的题竟然是小夏令营题想想就好可怕TAT(你萌不知道什么是XJB算法???)
讲道理这道题的标程虽然奇短无比但是想法还是蛮有启发意义的。。。我试着口胡一下原理QAQ
先考虑无元素重复的情况:
首先会得到N+1个序列的按字典序排列的最后一个值
![](data/attach/1904/l9mpt71vg3v9h1tmqla7i1lf5dnqonvk.jpg)
对于每一个序列,为了表达方便,我们扯一个三元组
![](data/attach/1904/goqwusl043mh5k2nuvxqqckvvitahc4g.jpg)
出来,注意到所有
![](data/attach/1904/qg56zr0rpwvn02sp0n5r6bz5xgkwcoij.jpg)
组成的集合和
![](data/attach/1904/z3cbxb5jcv0va2q8hwghysiabyak4jjx.jpg)
组成的集合一模一样(一个环上所有相邻元素的集合)。
而我们得到的序列就是将所有三元组
![](data/attach/1904/ic2sr5hugwciarcnczn7ideyqtj1iit1.jpg)
按照
![](data/attach/1904/6vulv5pwq36v4xjos8ugus96tskhjr5o.jpg)
双关键字排序之后输出的
![](data/attach/1904/hmhmxlf12dvi5i1b53lnyz9cueeocr2x.jpg)
序列。
注意到所有
![](data/attach/1904/hjtif7z22ljy36gg7akrafa5o5jgejde.jpg)
组成的集合和
![](data/attach/1904/6udzpsta0uudvnyk6mj2m5pmcqktxrbp.jpg)
组成的集合一模一样,所以我们先把这个集合给弄出来,我们将得到的原序列复制一遍,由小到大排序后和原序列粘到一起再排一遍序(实现技巧见代码),至此我们弄出了按照
![](data/attach/1904/z47070c4de59d93nni2ihjx43udqgyba.jpg)
排序的数字对序列
![](data/attach/1904/mu7eqam6vuqsw4wpg8womw63shvex28s.jpg)
,这也是按照
![](data/attach/1904/u4sn5p9lvmel4yqlixy1zkkt3bym7abw.jpg)
排序的数字对序列。
#前方有点难说清楚我尽量
设答案序列也就是原序列为
![](data/attach/1904/qksz9l9uw70yhmlaj1sdqgcxmoquaal5.jpg)
,设给出的序列为
![](data/attach/1904/6n9j7a3fsm6e06hoawed5vlr8b1x9uwf.jpg)
首先我们在原序列中找到唯一的一个0的位置,假设它在给出的原序列中的位置是K(
![](data/attach/1904/nvjj8az3dolykcod1i5n6qa7vqsjda6u.jpg)
),那么我们就知道
![](data/attach/1904/iwa5ihm3ullxwgll6dc1e2ag7nbll0g3.jpg)
是序列
![](data/attach/1904/l527b8atzhq1yj6sv1buniphy716jd5z.jpg)
中的第K个元素。但是!我们已经得到了
![](data/attach/1904/bxt8x4bbd1x15934btqeccip5ofud8vd.jpg)
序列,所以我们就可以得到
![](data/attach/1904/rgk8j4flbwrem3xu3wkwy4iu1t04oncm.jpg)
的值。
然后我们发现,如果我们再在原序列
![](data/attach/1904/wbn1fgyxoeffw3r84buox2d3sgzgy8h3.jpg)
中
![](data/attach/1904/1gi3sfz5gefwlndvrggh9mkdzbmqgiln.jpg)
的位置,一切找
![](data/attach/1904/1sixm07gk0jyg0t4tjst6luhqac6tkgz.jpg)
的过程就和找
![](data/attach/1904/cy1qkla7ceoxftfsxdlubjowh3w6lo18.jpg)
一模一样辣!!!
以上
至于有重复元素的情况。。。把双关键字排序改成带下标的三关键字稳定排序就可以辣!!!(我不知道为什么但原理应该相通)
#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]