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\n",Getlca(a,b));
61 }
62 return 0;
63 }
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\n");
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\n");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 }
主要反思一下:
考试策略不好,时间分配不合理,难度评估sb 认为T1最难,T3最水?????????
端正心态,不要去刚题,但也不要轻易放弃(暴力还是要打的)
原文:https://www.cnblogs.com/hzoi-kx/p/11296296.html