首页 > 其他 > 详细

模拟12题解(未完)

时间:2019-08-03 19:11:58      阅读:91      评论:0      收藏:0      [点我收藏+]

T1[A. 斐波那契(fibonacci)]

考场上发现了一个性质:一个节点的父节点=该节点编号-上一个fibonacci数

所以求父亲节点代码

 

int fa(int x)
{
    for(int i=mx;i;i--)
        if(fi[i]<x)
            return x-fi[i];
}

 

然后我只想到了建树的70%代码,数组越界了又少了30分QAQ

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define int long long
 7 using namespace std;
 8 inline int read()
 9 {
10     int f=1,x=0;char ch=getchar();
11     while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
12     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
13     return f*x;
14 }
15 const int mx=65;
16 const int maxn=1000000;
17 int fi[mx+10];
18 int d[maxn+5];
19 int f[maxn+5][25];
20 struct node{
21     int v,nxt;
22 }e[maxn];int h[maxn],nu;
23 void add(int x,int y)
24 {
25     e[++nu].v=y;
26     e[nu].nxt=h[x];
27     h[x]=nu;
28 }
29 int gfa(int x)
30 {
31     for(int i=mx;i;i--)
32         if(fi[i]<x)
33             return x-fi[i];
34 }
35 void bfs()
36 {
37     queue<int>q;
38     d[1]=1;
39     q.push(1);
40     while(q.size())
41     {
42         int x=q.front();q.pop();
43         for(int i=h[x];i;i=e[i].nxt)
44         {
45             int y=e[i].v;
46             if(d[y])continue;
47             d[y]=d[x]+1;
48             f[y][0]=x;
49             for(int j=1;j<=21;j++)
50                 f[y][j]=f[f[y][j-1]][j-1];
51             q.push(y);
52         }
53     }
54 }
55 int lca(int x,int y)
56 {
57     if(d[x]>d[y])swap(x,y);
58     for(int i=21;i>=0;i--)
59         if(d[f[y][i]]>=d[x])
60             y=f[y][i];
61     if(y==x)return x;
62     for(int i=21;i>=0;i--)
63         if(f[x][i]!=f[y][i])
64             x=f[x][i],y=f[y][i];
65     return f[x][0];    
66 }
67 signed main()
68 {
69     //freopen("fibonacci2.in","r",stdin);
70     int m=read(),mxx;
71     fi[0]=fi[1]=1;
72     for(int i=2;i<=mx;i++)
73         fi[i]=fi[i-1]+fi[i-2];
74     for(int i=2;i<=maxn;i++)
75     {
76         int fa=gfa(i);
77         add(fa,i);
78     }
79     bfs();
80     for(int i=1;i<=m;i++)
81     {
82         int x=read(),y=read();
83         printf("%lld\n",lca(x,y));
84     }
85 }
86 /*
87 g++ 1.cpp -o 1
88 ./1
89 
90 */
View Code

可是考完才发现暴力既好写,又能A

对于输入的两个节点x,y将其中一个向上遍历,并把经过的路径都存入一个vector

然后另一个向上翻,如果在vector中能找到,那此时的y就是答案

时间复杂度O(玄学)

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 #define int long long
 8 using namespace std;
 9 inline int read()
10 {
11     int f=1,x=0;char ch=getchar();
12     while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
13     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
14     return f*x;
15 }
16 const int mx=65;
17 int fi[mx+10];
18 int fa(int x)
19 {
20     for(int i=mx;i;i--)
21         if(fi[i]<x)
22             return x-fi[i];
23 }
24 signed main()
25 {
26     //freopen("data","r",stdin);
27     int m=read();
28     fi[0]=fi[1]=1;
29     for(int i=2;i<=mx;i++)
30         fi[i]=fi[i-1]+fi[i-2];
31     vector<int>v;
32     for(int i=1;i<=m;i++)
33     {
34         int x=read(),y=read();
35         v.clear();
36         while(x>1)
37         {
38             v.push_back(x);
39             x=fa(x);
40         }
41         while(y>1)
42         {
43             vector<int>::iterator res=find(v.begin(),v.end(),y);
44             if(res!=v.end())  break;
45             y=fa(y);
46         }
47         printf("%lld\n",y);
48     }
49 }
50 /*
51 g++ 1.cpp -o 1
52 ./1
53 
54 */
View Code

vector中查找元素:

vector<int>::iterator res=find(v.begin(),v.end(),y);//在v中查找y
if(res!=v.end()) //找到了 

 

T2[B. 数颜色]「排序」「线段树」「分块」「莫队」

考场上只想到了$O(nm)$的纯暴力,

然而以上的这些都能拿到不少的部分分,更有主席树,树套树的高超方法,我却什么都搞不出来

正解:

将(颜色,位置)按照二元组排序,对于查询操作,使用结构体lower_bound二分查找

对于修改操作,暴力修改结构体的pos,

注意若两个颜色不同,那么修改不会改变每个颜色块里的顺序

若相同,不用修改

技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define mid ((l+r)>>1)
 6 using namespace std;
 7 const int maxn=3e5+5;
 8 inline int read()
 9 {
10     int f=1,x=0;char ch=getchar();
11     while(ch>9||ch<0){if(ch==-)f=-1;ch=getchar();}
12     while(ch<=9&&ch>=0){x=(x<<3)+(x<<1)+ch-0;ch=getchar();}
13     return f*x;
14 }
15 int n,sum[maxn],jl[maxn]; 
16 struct node{
17     int pos,da;
18 }a[maxn];
19 bool cmp(node x,node y){return (x.da==y.da)?x.pos<y.pos:x.da<y.da;}
20 int main()
21 {
22 //    freopen("data","r",stdin);
23     n=read();int Q=read(),mc=0;
24     for(int i=1;i<=n;i++)
25     {
26         a[i].da=read(),a[i].pos=i;
27         sum[a[i].da]++;
28         mc=max(mc,a[i].da);
29         jl[i]=a[i].da;
30     }
31     for(int i=1;i<=mc;i++)
32         sum[i]+=sum[i-1];
33     sort(a+1,a+n+1,cmp);
34     while(Q--)
35     {
36         int opt=read();
37         if(opt==1)
38         {
39             int L=read(),R=read(),col=read();
40             node l,r;
41             l.da=col,l.pos=L;
42             r.da=col,r.pos=R;
43             int ll=lower_bound(a+sum[col-1]+1,a+sum[col]+1,l,cmp)-a;
44             int rr=upper_bound(a+sum[col-1]+1,a+sum[col]+1,r,cmp)-a;
45             printf("%d\n",rr-ll);
46         }
47         if(opt==2)
48         {
49             int i=read();
50             int x=i,y=i+1;
51             if(jl[x]==jl[y])continue;
52             node xx,yy;
53             xx.pos=x,xx.da=jl[x];int c1=jl[x];
54             yy.pos=y,yy.da=jl[y];int c2=jl[y];
55             int xp=lower_bound(a+sum[c1-1]+1,a+sum[c1]+1,xx,cmp)-a;
56             int yp=lower_bound(a+sum[c2-1]+1,a+sum[c2]+1,yy,cmp)-a;
57             a[xp].pos=y,a[yp].pos=x;
58             jl[x]=yy.da,jl[y]=xx.da;
59         }
60     }
61 }
62 /*
63 g++ 2.cpp -o 2
64 ./2
65 
66 */
View Code

结构体lower_bound:

bool cmp(node x,node y){return (x.da==y.da)?x.pos<y.pos:x.da<y.da;}
int ll=lower_bound(a+1,a+n+1,l,cmp)-a;//a中查找l返回下标ll

 

模拟12题解(未完)

原文:https://www.cnblogs.com/casun547/p/11295672.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!