比赛补题
疑难杂题 代码源 + cf + 牛客 + atcoder + 知乎严鸽哥
数字替换 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include <bits/stdc++.h> using namespace std;const int N=5e5 +10 ;struct node { int t,x,y; }q[N]; int mp[N],n;vector<int >ans; signed main () { for (int i=0 ;i<N;i++)mp[i]=i; cin>>n; for (int i=1 ;i<=n;i++){ int t,x,y; cin>>t; if (t==1 ){ cin>>x; q[i]={t,x}; } else { cin>>x>>y; q[i]={t,x,y}; } } for (int i=n;i>=1 ;i--){ int t=q[i].t; int x=q[i].x; int y=q[i].y; if (t==2 )mp[x]=mp[y]; else ans.push_back (mp[x]); } reverse (ans.begin (),ans.end ()); for (auto x:ans)cout<<x<<" " ; }
画画 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
#include <bits/stdc++.h> using namespace std;int n,m;const int N=1100 ;int a[N][N];int get (int i,int j) { return (i-1 )*m+j; } struct node { int x,y,c; }q[N*N]; int xx[]={-1 ,-1 ,1 ,0 ,1 ,2 ,2 ,2 ,1 ,0 ,1 ,0 ,1 ,2 };int yy[]={-1 ,0 ,0 ,-1 ,1 ,-1 ,0 ,1 ,0 ,1 ,1 ,2 ,2 ,2 };int dx[]={0 ,1 ,0 ,1 };int dy[]={0 ,0 ,1 ,1 };int check (int x,int y) { int p=-1 ; for (int t=0 ;t<4 ;t++){ int i=x+dx[t]; int j=y+dy[t]; if (i<1 ||i>n||j<1 ||j>m)return 0 ; int c=a[i][j]; if (c==-1 )continue ; if (p==-1 )p=c; if (c!=p)return 0 ; } return 1 ; } int vis[N][N];signed main () { ios::sync_with_stdio (0 ); cin>>n>>m; for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++)cin>>a[i][j]; } int hh=0 ,tt=0 ; for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++){ if (check (i,j)){ q[tt++]={i,j,a[i][j]}; vis[i][j]=1 ; } } } if (hh==tt){ cout<<"-1" ; return 0 ; } stack<node>ans; while (hh<tt){ auto t=q[hh++]; ans.push (t); int x=t.x,y=t.y,c=t.c; a[x][y]=-1 ,a[x+1 ][y]=-1 ,a[x][y+1 ]=-1 ,a[x+1 ][y+1 ]=-1 ; for (int t=0 ;t<14 ;t++){ int i=x+xx[t]; int j=y+yy[t]; if (i<1 ||i>n||j<1 ||j>m)continue ; if (vis[i][j])continue ; int c=-1 ; if (check (i,j)){ if (a[i][j]!=-1 )c=a[i][j]; if (a[i+1 ][j]!=-1 )c=a[i+1 ][j]; if (a[i][j+1 ]!=-1 )c=a[i][j+1 ]; if (a[i+1 ][j+1 ]!=-1 )c=a[i+1 ][j+1 ]; if (c==-1 )c=1 ; q[tt++]={i,j,c}; vis[i][j]=1 ; } } } cout<<ans.size ()<<'\n' ; while (ans.size ()){ auto t=ans.top (); ans.pop (); cout<<t.x<<" " <<t.y<<" " <<t.c<<'\n' ; } }
小雨坐地铁(分层图_牛客博客 (nowcoder.net)
环的数量 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
#include <bits/stdc++.h> using namespace std;const int N=20 ,M=1 <<N;int f[M][N],n,m,g[N][N];long long ans;int lowbit (int x) {return (int )log2 (x&-x);}int cal (int x) { int cnt=0 ; while (x)cnt+=x&1 ,x>>=1 ; return cnt; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>n>>m; int mm=m; while (m--){ int a,b; cin>>a>>b; a--,b--; g[a][b]=g[b][a]=1 ; } for (int i=0 ;i<n;i++)f[1 <<i][i]=1 ; for (int i=1 ;i<1 <<n;i++){ int u=lowbit (i); for (int j=0 ;j<n;j++){ if (!(i>>j&1 ))continue ; if (g[u][j])ans+=f[i][j]; for (int k=u+1 ;k<n;k++){ if (i>>k&1 )continue ; if (!g[j][k])continue ; f[i|(1 <<k)][k]+=f[i][j]; } } } cout<<(ans-mm)/2 ; }
最大权值划分 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <bits/stdc++.h> using namespace std;const int N=1e6 +10 ;#define int long long int a[N],f[N][2 ],n;signed main () { ios::sync_with_stdio (0 ); cin>>n; for (int i=1 ;i<=n;i++)cin>>a[i]; for (int i=2 ;i<=n;i++){ if (a[i]<a[i-1 ]){ f[i][0 ]=max (f[i-1 ][0 ]+a[i-1 ]-a[i],f[i-1 ][1 ]); f[i][1 ]=max (f[i-1 ][0 ],f[i-1 ][1 ]); } else { f[i][1 ]=max (f[i-1 ][1 ]+a[i]-a[i-1 ],f[i-1 ][0 ]); f[i][0 ]=max (f[i-1 ][1 ],f[i-1 ][0 ]); } } cout<<max (f[n][0 ],f[n][1 ]); }
Ayoub’s function - 题目 - Daimayuan Online Judge
组合数学+思维
(8条消息) Ayoub’s function CodeForces - 1301C(组合数学)_starlet_kiss的博客-CSDN博客
括号序列 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
#include <bits/stdc++.h> using namespace std;string s; const int N=1e6 +10 ;int f[N],match[N];signed main () { while (cin>>s){ memset (f,0 ,sizeof f); stack<int >stk; int n =s.length (); for (int i=1 ;i<=n;i++){ if (s[i-1 ]=='(' )stk.push (i); else { if (stk.empty ())continue ; else match[i]=stk.top (),stk.pop (); } } for (int i=1 ;i<=n;i++){ if (s[i-1 ]==')' &&match[i])f[i]=f[match[i]-1 ]+1 ; } long long ans=0 ; for (int i=1 ;i<=n;i++){ if (s[i-1 ]==')' &&match[i])ans+=f[i]; } cout<<ans<<'\n' ; } }
弗拉德和糖果 II - 题目 - Daimayuan Online Judge
贪心+小思维
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include <iostream> #include <cstring> #include <algorithm> using namespace std;#define int long long int sum,ma,n;signed main () { ios::sync_with_stdio (0 ); cin>>n; for (int i=1 ;i<=n;i++){ int x; cin>>x; sum+=x; ma=max (ma,x); } if (ma-1 >sum-ma)puts ("NO" ); else puts ("YES" ); }
任务分配 - 题目 - Daimayuan Online Judge
质区间长度 - 题目 - Daimayuan Online Judge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include <bits/stdc++.h> using namespace std;const int N=1e6 +10 ;int primes[N],cnt,st[N],l,r,k,a[N];void init () { st[1 ]=1 ; for (int i=2 ;i<N;i++){ if (!st[i])primes[cnt++]=i; for (int j=0 ;i*primes[j]<N;j++){ st[primes[j]*i]=1 ; if (i%primes[j]==0 )break ; } } } int check (int mid) { for (int i=l;i<=r;i++){ int j=i+mid-1 ; if (j>r)break ; if (a[j]-a[i-1 ]<k)return 0 ; } return 1 ; } signed main () { init (); cin>>l>>r>>k; for (int i=l;i<=r;i++){ if (!st[i])a[i]=a[i-1 ]+1 ; else a[i]=a[i-1 ]; } if (a[r]-a[l-1 ]<k){ cout<<"-1" ; return 0 ; } int L=k,R=r-l+1 ; while (L<R){ int mid=L+R>>1 ; if (check (mid))R=mid; else L=mid+1 ; } cout<<max (1 ,R); }
4009. 收集卡牌 - AcWing题库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
#include <iostream> #include <cstring> #include <algorithm> using namespace std;const int N=16 ,M=1 <<N;int n,k;double p[N],f[M][N*5 +1 ];double dfs (int x,int sum,int need) { if (f[x][sum]>=0 )return f[x][sum]; if (sum>=need*k)return f[x][sum]=0 ; f[x][sum]=0 ; for (int i=0 ;i<n;i++){ if (x>>i&1 )f[x][sum]+=p[i]*(dfs (x,sum+1 ,need)+1 ); else f[x][sum]+=p[i]*(dfs (x^(1 <<i),sum,need-1 )+1 ); } return f[x][sum]; } signed main () { cin>>n>>k; for (int i=0 ;i<n;i++)cin>>p[i]; memset (f,-1 ,sizeof f); cout<<dfs (0 ,0 ,n); }
1212. 地宫取宝 - AcWing题库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
#include <cstring> #include <iostream> #include <algorithm> using namespace std;const int N = 55 , MOD = 1000000007 ;int n, m, k;int w[N][N];int f[N][N][13 ][14 ];int main () { cin >> n >> m >> k; for (int i = 1 ; i <= n; i ++ ) for (int j = 1 ; j <= m; j ++ ) { cin >> w[i][j]; w[i][j] ++ ; } f[1 ][1 ][1 ][w[1 ][1 ]] = 1 ; f[1 ][1 ][0 ][0 ] = 1 ; for (int i = 1 ; i <= n; i ++ ) for (int j = 1 ; j <= m; j ++ ) { if (i == 1 && j == 1 ) continue ; for (int u = 0 ; u <= k; u ++ ) for (int v = 0 ; v <= 13 ; v ++ ) { int &val = f[i][j][u][v]; val = (val + f[i - 1 ][j][u][v]) % MOD; val = (val + f[i][j - 1 ][u][v]) % MOD; if (u > 0 && v == w[i][j]) { for (int c = 0 ; c < v; c ++ ) { val = (val + f[i - 1 ][j][u - 1 ][c]) % MOD; val = (val + f[i][j - 1 ][u - 1 ][c]) % MOD; } } } } int res = 0 ; for (int i = 0 ; i <= 13 ; i ++ ) res = (res + f[n][m][k][i]) % MOD; cout << res << endl; return 0 ; }
4381. 翻转树边 - AcWing题库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#include <bits/stdc++.h> using namespace std;const int N = 2e5 + 10 , M = 2 * N;int h[N], ne[M], e[M], w[M], idx, dp[N];void add (int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } int f[N];void dfs1 (int u, int fa) { for (int i = h[u]; i != -1 ; i = ne[i]) { int j = e[i], k = w[i]; if (j == fa) continue ; dfs1 (j, u); f[u] += f[j] + k; } } void dfs2 (int u, int fa) { for (int i = h[u]; i != -1 ; i = ne[i]) { int j = e[i], k = w[i]; if (j == fa) continue ; dp[j] = dp[u] + (k == 1 ? 0 : 1 ) - (k == 1 ? 1 : 0 ); dfs2 (j, u); } } int main () { int n; cin >> n; memset (h, -1 , sizeof h); for (int i = 1 ; i < n; i++) { int a, b; cin >> a >> b; add (a, b, 0 ), add (b, a, 1 ); } dfs1 (1 , -1 ); dp[1 ] = f[1 ]; dfs2 (1 , -1 ); int mx = 0x3f3f3f3f ; for (int i = 1 ; i <= n; i++) mx = min (mx, dp[i]); cout << mx << "\n" ; for (int i = 1 ; i <= n; i++) if (dp[i] == mx) cout << i << " " ; return 0 ; }
3111. 回转寿司 - AcWing题库
值域树状数组,离散化后求值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
#include <bits/stdc++.h> using namespace std;#define int long long const int N=3e5 +10 ;long long a[N],tr[N],n,L,R,ans,tot;vector<long long >xs; void add (int x,int c) { for (int i=x;i<N;i+=i&-i)tr[i]+=c; } long long sum (int x) { int ans=0 ; for (int i=x;i;i-=i&-i)ans+=tr[i]; return ans; } int get (long long x) { return lower_bound (xs.begin (),xs.end (),x)-xs.begin ()+1 ; } signed main () { cin>>n>>L>>R; for (int i=1 ;i<=n;i++){ cin>>a[i]; a[i]+=a[i-1 ]; } for (int i=1 ;i<=n;i++){ xs.push_back (a[i]); xs.push_back (a[i]-R-1 ); xs.push_back (a[i]-L); } sort (xs.begin (),xs.end ()); xs.erase (unique (xs.begin (),xs.end ()),xs.end ()); tot=xs.size (); add (get (a[0 ]),1 ); for (int i=1 ;i<=n;i++){ int x=get (a[i]); int y=get (a[i]-R-1 ); int z=get (a[i]-L); ans+=sum (z)-sum (y); add (x,1 ); } cout<<ans; }
4316. 合适数对 - AcWing题库
同方法题
2660. 方伯伯的玉米田 - AcWing题库
利用树状数组的dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
#include <iostream> #include <cstring> #include <algorithm> using namespace std;const int N=1e4 +10 ,M=550 ;int tr[M][N],a[N],n,k,ans;void add (int k,int v,int c) { for (int i=k;i<=551 ;i+=i&-i){ for (int j=v;j<=5500 ;j+=j&-j){ tr[i][j]=max (tr[i][j],c); } } } int sum (int k,int v) { int ans=0 ; for (int i=k;i;i-=i&-i){ for (int j=v;j;j-=j&-j){ ans=max (ans,tr[i][j]); } } return ans; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>n>>k; for (int i=1 ;i<=n;i++)cin>>a[i]; for (int i=1 ;i<=n;i++){ for (int j=k;j>=0 ;j--){ int t=sum (j+1 ,a[i]+j)+1 ; ans=max (ans,t); add (j+1 ,a[i]+j,t); } } cout<<ans; }
AcWing 2978. 最长上升子序列 - AcWing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
#include <bits/stdc++.h> using namespace std;const int N=1e5 +10 ;vector<int >a; int n,tr[N],dp[N];void add (int x,int c) { for (int i=x;i<=n;i+=i&-i)tr[i]=max (tr[i],c); } int sum (int x) { int ans=0 ; for (int i=x;i;i-=i&-i)ans=max (ans,tr[i]); return ans; } signed main () { cin>>n; for (int i=1 ;i<=n;i++){ int x; cin>>x; a.insert (x+a.begin (),i); } int ans=0 ; for (int i=0 ;i<n;i++){ int t=a[i]; dp[t]=sum (t)+1 ; add (t,dp[t]); } for (int i=1 ;i<=n;i++){ dp[i]=max (dp[i],dp[i-1 ]); cout<<dp[i]<<'\n' ; } } 作者:我已经不想再做刺客了 链接:https: 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1266. 校门外的树 - AcWing题库
很巧妙的思路 把区间想象成一条条线段 要求区间种数转化为求有多少个线段覆盖过这个区间 r之前的左端点数量减去l之前的右端点数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#include <iostream> #include <cstring> #include <algorithm> using namespace std;const int N=1e5 +10 ;int n,m,l,r,t1[N],t2[N],op;void add (int x,int tr[]) { for (int i=x;i<=n;i+=i&-i)tr[i]+=1 ; } int sum (int x,int tr[]) { int ans=0 ; for (int i=x;i;i-=i&-i)ans+=tr[i]; return ans; } signed main () { cin>>n>>m; while (m--){ cin>>op>>l>>r; if (op==1 ){ add (l,t1); add (r,t2); } else { cout<<sum (r,t1)-sum (l-1 ,t2)<<'\n' ; } } }
2952. 不等式组 - AcWing题库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
#include <bits/stdc++.h> #define endl '\n' using namespace std;const int N=2e6 +10 ;int n,t1[N],t2[N],ok,k[N],idx,vis[N],p[N];void add (int tr[],int x,int c) { for (int i=x;i<N;i+=i&-i)tr[i]+=c; } int sum (int tr[],int x) { int ans=0 ; for (int i=x;i;i-=i&-i)ans+=tr[i]; return ans; } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>n; for (int i=1 ;i<=n;i++){ string s; cin>>s; if (s[0 ]=='A' ){ int a,b,c; cin>>a>>b>>c; if (a==0 ){ if (b>c){ ok++; k[++idx]=1 ; } else { k[++idx]=0 ; } } if (a>0 ){ int x=floor ((1.0 *c-b)/a); if (x<-1e6 ){ ok++; k[++idx]=1 ; } else if (x>1e6 ){ k[++idx]=0 ; } else { add (t1,x+1e6 +1 ,1 ); k[++idx]=2 ; p[idx]=x+1e6 +1 ; } } if (a<0 ){ int x=ceil ((1.0 *c-b)/a); if (x>1e6 ){ ok++; k[++idx]=1 ; } else if (x<-1e6 ){ k[++idx]=0 ; } else { add (t2,x+1e6 +1 ,1 ); k[++idx]=3 ; p[idx]=x+1e6 +1 ; } } } if (s[0 ]=='Q' ){ int x; cin>>x; x+=1e6 +1 ; int ans1=sum (t1,x-1 ); int ans2=sum (t2,N-1 )-sum (t2,x); cout<<ans1+ans2+ok<<endl; } if (s[0 ]=='D' ){ int x; cin>>x; if (vis[x])continue ; vis[x]=1 ; if (k[x]==1 )ok--; if (k[x]==2 )add (t1,p[x],-1 ); if (k[x]==3 )add (t2,p[x],-1 ); } } }
4081. 选数 - AcWing题库
混合背包dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#include <iostream> #include <cstring> #include <algorithm> using namespace std;const int N=220 ,M=200 *26 ;#define int long long int f[N][M];int n,k;signed main () { cin>>n>>k; memset (f,-0x3f ,sizeof f); f[0 ][0 ]=0 ; for (int i=1 ;i<=n;i++){ int a; cin>>a; int w=0 ; int v=0 ; while (a%5 ==0 )a/=5 ,w++; while (a%2 ==0 )a/=2 ,v++; for (int j=k;j>=1 ;j--){ for (int t=M-1 ;t>=w;t--){ f[j][t]=max (f[j][t],f[j-1 ][t-w]+v); } } } int ans=0 ; for (int i=1 ;i<M;i++)ans=max (ans,min (i,f[k][i])); cout<<ans; }
3281. 城市规划 - AcWing题库
树形dp 分组背包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#include <iostream> #include <cstring> #include <algorithm> using namespace std;const int N = 5e4 +10 ,M=2 *N;const long long INF=0x3f3f3f3f3f3f3f3f ;int h[N],ne[M],e[M],idx,n,m,K;int s[N];int st[N];long long w[M];long long f[N][110 ];long long ans=INF;void add (int a,int b,int c) { e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++; } void dfs (int u,int fa) { f[u][0 ]=0 ; if (st[u])f[u][1 ]=0 ,s[u]=1 ; for (int i=h[u];~i;i=ne[i]){ int j=e[i]; if (j==fa)continue ; dfs (j,u); s[u]+=s[j]; for (int k=min (s[u],K);k>=0 ;k--){ for (int x=0 ;x<=min (k,s[j]);x++) f[u][k]=min (f[u][k],f[u][k-x]+f[j][x]+w[i]*x*(K-x)); } } ans=min (ans,f[u][K]); } signed main () { memset (h, -1 , sizeof h); cin>>n>>m>>K; while (m--){ int x; scanf ("%d" ,&x); st[x]=1 ; } for (int i=1 ;i<n;i++){ int a,b,c; scanf ("%d %d %d" ,&a,&b,&c); add (a,b,c); add (b,a,c); } memset (f,0x3f3f ,sizeof f); dfs (1 ,-1 ); cout<<ans; }
E-禅_牛客小白月赛49 (nowcoder.com)
思维递推
从起点p向两边递推,考虑每个单调区间,这种做法是错误的
比如2 2 2 2 1 10 0
从最左边开始代价是最小的,会一直加
那么既然无法确定起点,如何处理这n方复杂度?
设dp【i】表示从点i开始的代价,考虑答案之间的递推关系
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#include <bits/stdc++.h> using namespace std;#define int long long const int N=1e5 +10 ;int n,a[N],T,f[N];signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>T; while (T--){ cin>>n; int p; for (int i=1 ;i<=n;i++){ cin>>a[i]; if (a[i]==0 )p=i; } if (n==1 ){ cout<<"No Solution" <<'\n' ; continue ; } for (int i=1 ;i<=n;i++)f[i]=0 ; f[p-1 ]=a[p-1 ]+1 ; f[p+1 ]=a[p+1 ]+1 ; for (int i=p+2 ;i<=n;i++)f[i]=max (a[i]+1 ,f[i-1 ]-a[i]); for (int i=p-2 ;i>=1 ;i--)f[i]=max (a[i]+1 ,f[i+1 ]-a[i]); int ans=1e9 ; for (int i=1 ;i<=n;i++){ if (i==p)continue ; ans=min (ans,f[i]); } cout<<ans<<'\n' ; } }
二维RMQ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#include <bits/stdc++.h> using namespace std;const int N=1100 ;int ma[N][N][11 ],mi[N][N][11 ],n,a[N][N],p,m,k;int ans=1e9 ;int qmax (int i,int j) { int ma1=max (ma[i][j][k],ma[i+p-(1 <<k)][j+p-(1 <<k)][k]); int ma2=max (ma[i+p-(1 <<k)][j][k],ma[i][j+p-(1 <<k)][k]); return max (ma1,ma2); } int qmin (int i,int j) { int mi1=min (mi[i][j][k],mi[i+p-1 -(1 <<k)+1 ][j+p-(1 <<k)][k]); int mi2=min (mi[i+p-1 -(1 <<k)+1 ][j][k],mi[i][j+p-(1 <<k)][k]); return min (mi1,mi2); } signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>n>>m>>p;k=log2 (p); for (int i=1 ;i<=n;i++){ for (int j=1 ;j<=m;j++){ cin>>a[i][j]; ma[i][j][0 ]=a[i][j]; mi[i][j][0 ]=a[i][j]; } } for (int k=1 ;k<=10 ;k++){ for (int i=1 ;i+(1 <<k-1 )<=n;i++){ for (int j=1 ;j+(1 <<k-1 )<=m;j++){ int ma1=max (ma[i][j][k-1 ],ma[i+(1 <<k-1 )][j+(1 <<k-1 )][k-1 ]); int ma2=max (ma[i+(1 <<k-1 )][j][k-1 ],ma[i][j+(1 <<k-1 )][k-1 ]); ma[i][j][k]=max (ma1,ma2); int mi1=min (mi[i][j][k-1 ],mi[i+(1 <<k-1 )][j+(1 <<k-1 )][k-1 ]); int mi2=min (mi[i+(1 <<k-1 )][j][k-1 ],mi[i][j+(1 <<k-1 )][k-1 ]); mi[i][j][k]=min (mi1,mi2); } } } for (int i=1 ;i+p-1 <=n;i++){ for (int j=1 ;j+p-1 <=m;j++){ ans=min (ans,qmax (i,j)-qmin (i,j)); } } cout<<ans; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
#include <bits/stdc++.h> using namespace std;#define int long long const int N=2e5 +10 ;int n,m;int ru[N],chu[N],vis[N];vector<int >g[N]; int f[N],ans=1 ;int dfs (int u) { if (chu[u]<=1 )return f[u]=1 ; if (f[u])return f[u]; f[u]=1 ; for (auto j:g[u]){ dfs (j); if (ru[j]>=2 )f[u]=max (f[u],f[j]+1 ); } ans=max (ans,f[u]); return f[u]; } signed main () { ios::sync_with_stdio (0 ); cin>>n>>m; for (int i=1 ;i<=m;i++){ int a,b; cin>>a>>b; chu[a]++,ru[b]++; g[a].push_back (b); } for (int i=1 ;i<=n;i++)dfs (i); cout<<ans; }
F-牛牛的猜球游戏_牛客竞赛数据结构专题班前缀和练习题 (nowcoder.com)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
#include <bits/stdc++.h> using namespace std;const int N=1e5 +10 ;int f[N][10 ],ans[N];int n,m;signed main () { ios::sync_with_stdio (0 ); cin.tie (0 ); cout.tie (0 ); cin>>n>>m; for (int i=0 ;i<10 ;i++)f[0 ][i]=i; for (int i=1 ;i<=n;i++){ int l,r; cin>>l>>r; for (int j=0 ;j<10 ;j++)f[i][j]=f[i-1 ][j]; swap (f[i][l],f[i][r]); } while (m--){ int l,r; cin>>l>>r; for (int i=0 ;i<10 ;i++)ans[ f[l-1 ][i] ]=i; for (int i=0 ;i<10 ;i++)cout<<ans[ f[r][i] ]<<" " ; cout<<'\n' ; } }