欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷 P3960 列队【线段树】

发布时间:2025/7/14 编程问答 31 豆豆
生活随笔 收集整理的这篇文章主要介绍了 洛谷 P3960 列队【线段树】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

用动态开点线段树分别维护每一行和最后一列,线段树的作用是记录被选的点的个数以及查询第k个没被选的点,每次修改,从行里标记被选的点,从最后一列标记向左看齐之后少的点,然后用vector维护行列的新增点

#include<iostream> #include<cstdio> #include<vector> using namespace std; const int N=600005; int n,m,q,mx,tot,rt[N]; vector<long long>a[N]; struct qwe {int ls,rs,s; }t[10000005]; int read() {int r=0,f=1;char p=getchar();while(p>'9'||p<'0'){if(p=='-')f=-1;p=getchar();}while(p>='0'&&p<='9'){r=r*10+p-48;p=getchar();}return r*f; } void update(int &ro,int l,int r,int p) {if(!ro)ro=++tot;t[ro].s++;if(l==r)return;int mid=(l+r)>>1;if(p<=mid)update(t[ro].ls,l,mid,p);elseupdate(t[ro].rs,mid+1,r,p); } int ques(int ro,int l,int r,int k) {if(l==r)return l;int mid=(l+r)>>1;if(mid-l+1-t[t[ro].ls].s>=k)return ques(t[ro].ls,l,mid,k);elsereturn ques(t[ro].rs,mid+1,r,k-(mid-l+1-t[t[ro].ls].s)); } int main() {n=read(),m=read(),q=read(),mx=max(m,n)+q;while(q--){int x=read(),y=read();if(y==m){int p=ques(rt[n+1],1,mx,x);update(rt[n+1],1,mx,p);long long ans=p<=n?1ll*p*m:a[n+1][p-n-1];a[n+1].push_back(ans);printf("%lld\n",ans);}else{int p=ques(rt[x],1,mx,y);update(rt[x],1,mx,p);;long long ans=p<m?1ll*(x-1)*m+p:a[x][p-m];p=ques(rt[n+1],1,mx,x);update(rt[n+1],1,mx,p);long long ans2=p<=n?1ll*p*m:a[n+1][p-n-1];a[n+1].push_back(ans);a[x].push_back(ans2);printf("%lld\n",ans);}}return 0; }

转载于:https://www.cnblogs.com/lokiii/p/9709749.html

总结

以上是生活随笔为你收集整理的洛谷 P3960 列队【线段树】的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。