蓝书4.1-4.4 树状数组、RMQ问题、线段树、倍增求LCA

这章的数据结构题很真实

T1 排队 bzoj 1699

题目大意:

求静态一些区间的最大值-最小值

思路:

ST表裸题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 100100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,q,g[MAXN],mn[MAXN][20],mx[MAXN][20];
21 int main()
22 {
23     n=read(),q=read();int a,b,t;
24     for(int i=1;i<=n;i++) mn[i][0]=mx[i][0]=g[i]=read();
25     for(int j=1;j<20;j++)
26         for(int i=1;i+(1<<j)-1<=n;i++)
27             mn[i][j]=min(mn[i][j-1],mn[i+(1<<(j-1))][j-1]),mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
28     while(q--)
29     {
30         a=read(),b=read(),t=b-a+1,t=(int)log2(t);
31         printf("%d\n",max(mx[a][t],mx[b-(1<<t)+1][t])-min(mn[a][t],mn[b-(1<<t)+1][t]));
32     }
33 }
View Code

T2 选择客栈 luogu 1311

题目大意:

每个点有两个值 颜色和最小消费值 如果两个点对之间存在一个点最小消费值<=n

求这样的点对的个数

思路:

把每个颜色分别用链表存起来 记录上一个<=p的位置

对于每个颜色分别遍历

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<vector>
 9 #define ll long long
10 #define inf 2139062143
11 #define MAXN 200100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,k,p,g[MAXN],c[MAXN],tmp[60],fst[60],las,cnt,res,ans,l[MAXN],to[MAXN];
21 int main()
22 {
23     n=read(),k=read(),p=read();
24     for(int i=1;i<=n;i++)
25     {
26         c[i]=read(),g[i]=read();
27         if(g[i]<=p) las=i;l[i]=las;
28         if(!tmp[c[i]]) fst[c[i]]=i,tmp[c[i]]=i;
29         else to[tmp[c[i]]]=i,tmp[c[i]]=i;
30     }
31     for(int i=0,pos;i<k;i++)
32     {
33         pos=fst[i],cnt=1,res=0;
34         while(to[pos])
35         {
36             if(to[pos]>n) break;
37             if(l[to[pos]]>=pos) res=cnt;
38             ans+=res,cnt++,pos=to[pos];
39         }
40     }
41     printf("%d",ans);
42 }
View Code

T3 最大值  bzoj 1012

题解链接

T4 花神游历各国 bzoj 3211

题解链接

T5 维护序列 bzoj 1798

猜你喜欢

转载自www.cnblogs.com/yyc-jack-0920/p/9429765.html
今日推荐