「聯賽模擬測試30 」題解
阿新 • • 發佈:2020-11-20
T1.maze
沙雕題,不會建議重學最短路
提示:由於是稠密資料加強會卡掉afps
T2.bird
考試時受到貪婪大陸(查詢一段區間內不同區間的個數)的影響,使勁用起點終點去推,用線段樹維護,最後也沒能搞出來
考慮暴力,先運用初中物理知識把鳥動化成人在座標軸上走
定義狀態 \(f_i\) 表示當前位置在 \(i\) ,且在 \(i\) 開槍的最大收穫
轉移: \(f_i=max(f_j+b_i-c_{i,j})\) \(b_i\) 表示 \(i\) 上空的鳥的個數, \(c_{i,j}\) 表示 \(i,j\) 共有的線段個數
炡解是線段樹,動態維護最大值和共有鳥數,區間修改,區間查最大, \(O(nlogn)\)
/* cinput 4 5 -1 1 2 4 5 9 6 8 */ #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=8e5+5,maxe=1e6+5,INF=0x3f3f3f3f; inline int read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar(); return s*w; } int n,m,maxr,ans,f[maxn],b[maxn]; struct Node{ int l,r; }a[maxn]; bool cmp1(Node A,Node B){return A.l==B.l?A.r<B.r:A.l<B.l;} struct Segment_Tree{ int l,r,w,lazy; }tree[maxn*4]; vector<int> g1[maxn],g2[maxn]; #define mid ((l+r)>>1) void pushup(int rt){tree[rt].w=max(tree[rt*2].w,tree[rt*2+1].w);} void Build(int rt,int l,int r){ tree[rt].l=l,tree[rt].r=r; if(l==r)return; Build(rt*2,l,mid);Build(rt*2+1,mid+1,r); } void update(int rt,int w){ tree[rt].w+=w,tree[rt].lazy+=w; } void pushdown(int rt){ if(!tree[rt].lazy)return; update(rt*2,tree[rt].lazy);update(rt*2+1,tree[rt].lazy); tree[rt].lazy=0; } void modify(int rt,int s,int t,int w){ int l=tree[rt].l,r=tree[rt].r; if(s<=l&&r<=t)return update(rt,w),void(); pushdown(rt); if(s<=mid)modify(rt*2,s,t,w); if(mid<t)modify(rt*2+1,s,t,w); pushup(rt); } int query(int rt,int s,int t){ int l=tree[rt].l,r=tree[rt].r,sum=0; //if(t>s)return 0; if(s<=l&&r<=t)return tree[rt].w; pushdown(rt); if(s<=mid)sum=query(rt*2,s,t); if(mid<t)sum=max(sum,query(rt*2+1,s,t)); return sum; } int main(){ freopen("bird.in","r",stdin); freopen("bird.out","w",stdout); n=read(),m=read(); for(register int i=1;i<=n;i++){ a[i].l=max(read()+1,1),a[i].r=read()+1; if(a[i].r<1)continue; b[a[i].l]++;b[a[i].r+1]--; g1[a[i].l].push_back(a[i].r); g2[a[i].r].push_back(a[i].l); maxr=max(maxr,a[i].r); } for(register int i=1;i<=maxr;i++)b[i]+=b[i-1]; Build(1,1,maxr); for(register int i=1;i<=maxr;i++){ for(register int j=0;j<g1[i].size();j++)modify(1,i,g1[i][j],-1); int x=b[i]; if(i-m>=1)x+=query(1,1,i-m); //cout<<i<<" "<<x<<" "<<i-m<<" "<<b[i]<<" "<<query(1,1,i-m)<<" "<<g1[i].size()<<" "<<g2[i].size()<<endl; ans=max(ans,x); modify(1,i,i,x); for(register int j=0;j<g2[i].size();j++)modify(1,g2[i][j],i,1); } printf("%d\n",ans); return 0; }
T3.stone
貌似是神仙DP,沒改
T4.椎
線段樹維護單調棧,咕了
RUA~