蓝书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 }
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 }
T3 最大值 bzoj 1012
T4 花神游历各国 bzoj 3211
T5 维护序列 bzoj 1798
题目大意:
区间乘法和加法以及区间求和
思路:
维护两个tag 所有地方注意先乘后加
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 ll read() 14 { 15 ll 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 ll n,MOD,tp[MAXN<<2],tm[MAXN<<2],sum[MAXN<<2]; 21 void build(int k,int l,int r) 22 { 23 tm[k]=1; 24 if(l==r) {return ;} 25 int mid=(l+r)>>1; 26 build(k<<1,l,mid);build(k<<1|1,mid+1,r); 27 } 28 inline void pshd(int k,int l,int mid,int r) 29 { 30 (sum[k<<1]*=tm[k])%=MOD,(sum[k<<1|1]*=tm[k])%=MOD; 31 (tp[k<<1]*=tm[k])%=MOD,(tp[k<<1|1]*=tm[k])%=MOD; 32 (tm[k<<1]*=tm[k])%=MOD,(tm[k<<1|1]*=tm[k])%=MOD,tm[k]=1; 33 (sum[k<<1]+=tp[k]*(mid-l+1)%MOD)%=MOD,(sum[k<<1|1]+=tp[k]*(r-mid)%MOD)%=MOD; 34 (tp[k<<1]+=tp[k])%=MOD,(tp[k<<1|1]+=tp[k])%=MOD,tp[k]=0; 35 } 36 inline void mdfm(int k,int l,int r,int a,int b,ll x) 37 { 38 if(l==a&&r==b){(sum[k]*=x)%=MOD,(tp[k]*=x)%=MOD,(tm[k]*=x)%=MOD;return ;} 39 int mid=(l+r)>>1; 40 pshd(k,l,mid,r); 41 if(mid>=b) mdfm(k<<1,l,mid,a,b,x); 42 else if(mid<a) mdfm(k<<1|1,mid+1,r,a,b,x); 43 else {mdfm(k<<1,l,mid,a,mid,x);mdfm(k<<1|1,mid+1,r,mid+1,b,x);} 44 sum[k]=(sum[k<<1]+sum[k<<1|1])%MOD; 45 } 46 inline void mdfp(int k,int l,int r,int a,int b,ll x) 47 { 48 if(l==a&&r==b) {(sum[k]+=x*(r-l+1)%MOD)%=MOD,tp[k]+=x;return ;} 49 int mid=(l+r)>>1; 50 pshd(k,l,mid,r); 51 if(mid>=b) mdfp(k<<1,l,mid,a,b,x); 52 else if(mid<a) mdfp(k<<1|1,mid+1,r,a,b,x); 53 else {mdfp(k<<1,l,mid,a,mid,x);mdfp(k<<1|1,mid+1,r,mid+1,b,x);} 54 sum[k]=(sum[k<<1]+sum[k<<1|1])%MOD; 55 } 56 inline ll query(int k,int l,int r,int a,int b) 57 { 58 if(l==a&&r==b) return sum[k]; 59 int mid=(l+r)>>1; 60 pshd(k,l,mid,r); 61 if(mid>=b) return query(k<<1,l,mid,a,b); 62 else if(mid<a) return query(k<<1|1,mid+1,r,a,b); 63 else return (query(k<<1,l,mid,a,mid)+query(k<<1|1,mid+1,r,mid+1,b))%MOD; 64 } 65 int main() 66 { 67 n=read(),MOD=read();int a,b,c;build(1,1,n); 68 for(int i=1;i<=n;i++) mdfp(1,1,n,i,i,read()); 69 int T=read(); 70 while(T--) 71 { 72 a=read(); 73 if(a==1) {a=read(),b=read(),c=read();mdfm(1,1,n,a,b,c);} 74 else if(a==2) {a=read(),b=read(),c=read();mdfp(1,1,n,a,b,c);} 75 else if(a==3) {a=read(),b=read();printf("%lld\n",query(1,1,n,a,b));} 76 } 77 }