2022春每日一題:Day 36
阿新 • • 發佈:2022-03-14
題目:[JLOI2013]刪除物品
直接做顯然比較複雜,這個題是說對頂棧,但是可以把兩個棧拼在一起,記錄一下棧頂的下標,然後這樣這題就可以轉化為線性上的操作查詢了,用樹狀陣列簡單維護一下就ok了(某個數是否存在,單點修改+區間查詢)
程式碼:
#include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #define lowbit(x) x&-x const int N=1e5+5; using namespace std; int n1,n2,a[N],b[N],c[N],n,dy[N]; struct pos { int id,v; pos(int ii,int vv) { id=ii;v=vv; } pos(){ } friend bool operator < (pos a,pos b) { return a.v<b.v; } }nums[N]; namespace fenwick { struct fw { int c; }e[N]; void modify(int x,int v) { for(int i=x;i<=n;i+=lowbit(i)) e[i].c+=v; } int query(int x) { int ret=0; for(int i=x;i;i-=lowbit(i)) ret+=e[i].c; return ret; } } using namespace fenwick; int main() { scanf("%d %d",&n1,&n2); for(int i=1;i<=n1;i++) scanf("%d",&a[i]),c[n1-i+1]=a[i]; for(int i=1;i<=n2;i++) scanf("%d",&b[i]),c[n1+i]=b[i]; n=n1+n2; for(int i=1;i<=n;i++) nums[i]=pos(i,c[i]); sort(nums+1,nums+1+n); int last=-1,cnt=1; for(int i=1;i<=n;i++) { if(last!=nums[i].v) last=nums[i].v,cnt=i; dy[cnt]=nums[i].id; } for(int i=1;i<=n;i++) modify(dy[i],1); int now=n1; long long ret=0; for(int i=n;i;i--) { if(dy[i]<=now) { ret+=query(now)-query(dy[i]); now=dy[i]; } else { ret+=query(dy[i]-1)-query(now); now=dy[i]-1; } modify(dy[i],-1); } printf("%lld\n",ret); return 0; }