NOIP模拟测试12

T1 斐波那契

一道找规律题,被我做成了贼难的题。

观察图片可知x=f[i-1]+j。(j为x的父亲)且j<=f[i-1],然后就二分找父亲没了。

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int mod=233;
 5 ll f[61];
 6 struct Hush{
 7     int head[233],nxt[61],cnt;
 8     ll to[61];
 9     void insert(ll x)
10     {
11         int k=x%mod;
12         to[++cnt]=x;
13         nxt[cnt]=head[k];
14         head[k]=cnt;
15         return ;
16     }
17     bool find(ll x)
18     {
19         int k=x%mod;
20         for(int i=head[k];i;i=nxt[i])if(to[i]==x)return 1;
21         return 0;
22     }
23     void clear()
24     {
25         memset(head,0,sizeof(head));
26         cnt=0;
27     }
28 }H;
29 ll Getlca(ll a,ll b)
30 {
31     if(a>b)swap(a,b);
32     H.clear();
33     H.insert(a);
34     while(a!=1)
35     {
36         ll fa=lower_bound(f+1,f+61,a)-f;
37         fa=a-f[fa-1];
38         H.insert(fa);
39         a=fa;
40     }
41     if(H.find(b))return b;
42     while(b!=1)
43     {
44         ll fb=lower_bound(f+1,f+61,b)-f;
45         fb=b-f[fb-1];
46         if(H.find(fb))return fb;
47         b=fb;
48     }
49 }
50 int main()
51 {
52     f[0]=0;f[1]=1;
53     for(int i=2;i<=60;i++)f[i]=f[i-1]+f[i-2];
54     int m;
55     scanf("%d",&m);
56     for(int i=1;i<=m;i++)
57     {
58         ll a,b;
59         scanf("%lld%lld",&a,&b);
60         printf("%lld
",Getlca(a,b));
61     }
62     return 0;
63 }
View Code

T2 水题不说了

T3 分组

一道好题。

k=1:

以前做过一道菜肴制作,然后就可以知道:区间越往后放,就越靠前。然后就维护最长的区间即可

k=2:

用扩展域并查集,直接维护,特判很恶心。

  1 #include<bits/stdc++.h>
  2 #define MAXN 333333
  3 using namespace std;
  4 int nxt[MAXN],a[MAXN],pf[MAXN],dr[MAXN],f[MAXN];
  5 bool vst[MAXN];
  6 vector<int>ans,cl;
  7 inline int find(int x)
  8 {
  9     return f[x]==x?x:f[x]=find(f[x]);
 10 }
 11 inline void merge(int x,int y)
 12 {
 13     int fa=find(x),fb=find(y);
 14     f[fa]=fb;
 15     return ;
 16 }
 17 void bcj_clear(int l,int r)
 18 {
 19     for(int i=l;i<=r;i++)f[a[i]]=a[i],vst[a[i]]=0,dr[a[i]]=0;
 20     cl.clear();
 21     return ;
 22 }
 23 int main()
 24 {
 25     int n,k,maxa=0;
 26     scanf("%d%d",&n,&k);
 27         for(int i=1;i<=n;i++)
 28         {
 29             scanf("%d",&a[i]);
 30             maxa=max(maxa,a[i]);
 31         }
 32         int ed=n;
 33         for(int i=0;i<=1024;i++)pf[i]=i*i;
 34     if(k==1)
 35     {
 36         for(int i=n;i>=1;i--)
 37         {
 38             bool ok=1;
 39             for(int j=sqrt(maxa*2);j>=2&&pf[j]>=a[i];j--)
 40                 if(vst[pf[j]-a[i]]){ok=0;break;}
 41             if(!ok){
 42                 ed=i;
 43                 for(int k=0;k<cl.size();k++)
 44                     vst[cl[k]]=0;
 45                 cl.clear();
 46                 ans.push_back(i);
 47             }
 48             vst[a[i]]=1;
 49             cl.push_back(a[i]);
 50         }
 51         if(!ans.size())printf("1
");
 52         cout<<ans.size()+1<<endl;
 53         for(int i=ans.size()-1;i>=0;i--)
 54             printf("%d ",ans[i]);
 55         return 0;
 56     }
 57     else 
 58     {
 59         int last=n;
 60         for(int i=1;i<=maxa*2;i++)f[i]=i;
 61         for(int i=n;i>=1;i--)
 62         {
 63             bool ok=1;
 64             for(int j=sqrt(maxa*2);j>=2&&pf[j]>=a[i];j--)
 65             {
 66                 if(vst[pf[j]-a[i]]&&!vst[a[i]])
 67                 {
 68 //                    cout<<i<<"---"<<endl;
 69                     int now=pf[j]-a[i];
 70                     if(find(a[i])==find(now)){ok=0;break;}
 71                     if(!dr[now])dr[now]=a[i];
 72                     else if(dr[now]!=now)merge(dr[now],a[i]);
 73                     else {ok=0;break;}
 74                     if(!dr[a[i]])dr[a[i]]=now;
 75                     else if(dr[a[i]]!=a[i])merge(dr[a[i]],now);
 76                     else {ok=0;break;}
 77                 }
 78                 else if(vst[pf[j]-a[i]]&&a[i]==pf[j]-a[i])
 79                 {
 80 //                    cout<<i<<' '<<dr[a[i]]<<endl;
 81                     if(dr[a[i]]){ok=0;break;}
 82                     else dr[a[i]]=a[i];
 83                     //cout<<i<<' '<<a[i]<<")S"<<endl;
 84                 }
 85             }
 86             if(!ok){
 87                 ed=i;
 88                 bcj_clear(i,last);
 89                 last=i;
 90                 ans.push_back(i);
 91             }
 92             vst[a[i]]=1;
 93             cl.push_back(a[i]);
 94         }
 95         if(!ans.size()){printf("1
");return 0;}
 96         cout<<ans.size()+1<<endl;
 97         for(int i=ans.size()-1;i>=0;i--)
 98             printf("%d ",ans[i]);
 99         return 0;
100     }
101 }
View Code

主要反思一下:

考试策略不好,时间分配不合理,难度评估sb 认为T1最难,T3最水?????????

端正心态,不要去刚题,但也不要轻易放弃(暴力还是要打的)

原文地址:https://www.cnblogs.com/hzoi-kx/p/11296296.html