BZOJ2093: [Poi2010]Frog

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2093

题解:Orz这题好神!

        首先求一位数轴上距离每个点第k近的点。

        神做法:维护一个l,r表示a[l--r]是距离i最近的k个点,当i++时,只有可能l++,r++或不改变!!!

        然后比较两端距离大小就是第k大!!主要运用了待查询点往右移动时距离他最近的k个元素组成一个区间并且左右端点都单调不减!!!

        然后是倍增m,我以为处理处f[i][j]表示i走2^j步之后在哪里,每个倍增一次就好了。没想到卡空间!!!

        于是又orz了claris:

        

while(m)
    {
        if(m&1)
        {
            for1(i,n)t[i]=f[g[i]];
            for1(i,n)g[i]=t[i];
        }
        m>>=1;
        for1(i,n)t[i]=f[f[i]];
        for1(i,n)f[i]=t[i];
    }

       跪烂!!!!

代码:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<iostream>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 #include<string>
12 #define inf 1000000000
13 #define maxn 1000000+5
14 #define maxm 100000+5
15 #define eps 1e-10
16 #define ll long long
17 #define pa pair<int,int>
18 #define for0(i,n) for(int i=0;i<=(n);i++)
19 #define for1(i,n) for(int i=1;i<=(n);i++)
20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
22 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
23 #define mod 1000000007
24 using namespace std;
25 inline ll read()
26 {
27     ll x=0,f=1;char ch=getchar();
28     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
29     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
30     return x*f;
31 }
32 int n,k,f[maxn],g[maxn],t[maxn];
33 ll m,a[maxn];
34 int main()
35 {
36     freopen("input.txt","r",stdin);
37     freopen("output.txt","w",stdout);
38     n=read();k=read();m=read();
39     for1(i,n)a[i]=read();
40     int l=1,r=k+1;f[1]=k+1;
41     for2(i,2,n)
42     {
43         while(r<n&&a[r+1]-a[i]<a[i]-a[l])l++,r++;
44         f[i]=a[r]-a[i]>a[i]-a[l]?r:l;
45     }
46     for1(i,n)g[i]=i;
47     while(m)
48     {
49         if(m&1)
50         {
51             for1(i,n)t[i]=f[g[i]];
52             for1(i,n)g[i]=t[i];
53         }
54         m>>=1;
55         for1(i,n)t[i]=f[f[i]];
56         for1(i,n)f[i]=t[i];
57     }
58     for1(i,n)printf("%d%c",g[i],i==n?'\n':' ');
59     return 0;
60 }
View Code

 

posted @ 2015-02-01 11:56  ZYF-ZYF  Views(266)  Comments(0Edit  收藏  举报