先简单总结一下......
LYZ的题,还是挺好的。一点也不毒瘤。
还是有点考挂了......
第二题写了正解,然而并没有开long long......
T1水题我却没有看出来。
zwz大佬再次AK,太强了。
下面是T1 乖乖站好 standstill 的题解QAQ
这是一道神题。
思路极其......懂了正解之后感觉自己就是个xxx(手动和谐)。
然而我也只能说,这是道emmmm,好模拟。
题意:初始是1~n的序列。
每次变换如下:每k个为一组,组内第一个跑到最后一个的后面,最后不满k个的也视为一组。
即:若k=3,1 2 3 4 5会变成2 3 1 5 4
一共进行n-1次变换,k依次为2~n。
题解:暴力很好写,n方的。
每次变换的时候,一组的第一个要到最后一个的后面去,而这个位置也恰好被下一组的第一个让出来了(下一组的第一个也要往后走)。
这样对于组的大小为k的一次变换,只需要处理n/k个数。
最后的复杂度是n*(1/2+1/3+...+1/n)。
大概就是n*(H(n))(H(n)为调和级数部分和)
而根据某某数学定理,第n个调和数与n的自然对数的差值(即 )收敛于欧拉-马歇罗尼常数(这个常数约等于0.5772)。
所以总的复杂度就大概是n lg n。1e6的数据可在0.2s左右跑完(还是不加输出优化的)。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 6 int n; 7 int a[2000005]; 8 9 void print(int x) 10 { 11 if(x/10)print(x/10); 12 putchar(x%10+'0'); 13 } 14 15 int main() 16 { 17 freopen("standstill.in","r",stdin); 18 freopen("standstill.out","w",stdout); 19 scanf("%d",&n); 20 for(int i=1;i<=n;i++)a[i]=i; 21 for(int i=2;i<=n;i++) 22 { 23 int bef=n+i-1,p=(n-1)/i*i+i-1; 24 while(p>0) 25 { 26 a[bef]=a[p]; 27 bef=p; 28 p-=i; 29 } 30 } 31 for(int i=n;i<2*n;i++)print(a[i]),putchar(32); 32 fclose(stdin); 33 fclose(stdout); 34 return 0; 35 }