luogu P3285 [SCOI2014]方伯伯的OJ splay 線段樹
阿新 • • 發佈:2020-07-20
LINK:方伯伯的OJ
一道稍有質量的線段樹題目.不寫LCT splay這輩子是不會單獨寫的 真的!
喜聞樂見的是 題目迷惑選手 \(op==1\) 查改使用者在序列中的位置 題目壓根沒說位置啊 只有排名和編號 LOJ上寫的是 使用者在排名中的位置.
這說的不就是排名麼.
至此四個操作 分別為 修改編號查排名 查排名修改排名為第一位 查排名修改排名到最後一位 查排名為k的編號.
splay的做法 大概是分裂splay和動態開點splay 很好都不會.
直接考慮線段樹 因為可以注意到操作只有1e5個 而修改排名每次只不過把某個編號的排名放到前面或者後面 這個可以看成修改.
在前面和後面分別開1e5個位置即可.
考慮第一個操作 修改編號查排名 對於編號x 先查排名 我們需要知道的是 x在編號線上段樹的位置.
這個可以利用map 但是我用的hash比map更舒服一點.然後線段樹上直接查即可.
考慮修改 還是先把x的位置找到 然後進行修改什麼的.
最後一個操作 線段樹上二分 然後就能找到位置了 不過值得注意的是 要通過位置找編號 再來一個hash就做完了.
跑的飛快.hash果然比map香
code
//#include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<ctime> #include<cctype> #include<queue> #include<deque> #include<stack> #include<iostream> #include<iomanip> #include<cstdio> #include<cstring> #include<string> #include<ctime> #include<cmath> #include<cctype> #include<cstdlib> #include<queue> #include<deque> #include<stack> #include<vector> #include<algorithm> #include<utility> #include<bitset> #include<set> #include<map> #define ll long long #define db double #define INF 1000000000 #define ldb long double #define pb push_back #define put_(x) printf("%d ",x); #define get(x) x=read() #define gt(x) scanf("%d",&x) #define gi(x) scanf("%lf",&x) #define put(x) printf("%d\n",x) #define putl(x) printf("%lld\n",x) #define rep(p,n,i) for(RE int i=p;i<=n;++i) #define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]]) #define fep(n,p,i) for(RE int i=n;i>=p;--i) #define vep(p,n,i) for(RE int i=p;i<n;++i) #define pii pair<int,int> #define mk make_pair #define RE register #define P 1000000007ll #define gf(x) scanf("%lf",&x) #define pf(x) ((x)*(x)) #define uint unsigned long long #define ui unsigned #define EPS 1e-4 #define sq sqrt #define S second #define F first #define l(x) t[x].l #define r(x) t[x].r #define sum(p) t[p].sum #define zz p<<1 #define yy p<<1|1 #define M 1000003 using namespace std; char *fs,*ft,buf[1<<15]; inline char gc() { return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } inline int read() { RE int x=0,f=1;RE char ch=gc(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();} return x*f; } const int MAXN=100010; int n,m,ans,id,rt; int s1,s2,s3,s4; struct wy { int l,r; int sum; }t[MAXN*100]; struct jl { int lin[M],ver[M],nex[M],v[M],len; inline int find(int x) { int key=(ll)x*x%M; go(key)if(ver[i]==x)return v[i]; return x+100000; } inline int find1(int x) { int key=(ll)x*x%M; go(key)if(ver[i]==x)return v[i]; return x-100000; } inline void insert(int x,int y) { int key=(ll)x*x%M; go(key)if(ver[i]==x){v[i]=y;return;} ver[++len]=x;v[len]=y;nex[len]=lin[key];lin[key]=len; } }H,W; inline void modify(int &p,int l,int r,int L,int R) { if(!p)p=++id; if(l==r)return ++sum(p),void(); int mid=(l+r)>>1; if(L<=mid)modify(l(p),l,mid,L,R); if(R>mid)modify(r(p),mid+1,r,L,R); sum(p)=sum(l(p))+sum(r(p)); } inline int ask(int p,int l,int r,int L,int R) { if(!p)return 0; if(L<=l&&R>=r)return sum(p); int mid=(l+r)>>1; if(R<=mid)return ask(l(p),l,mid,L,R); if(L>mid)return ask(r(p),mid+1,r,L,R); return ask(l(p),l,mid,L,R)+ask(r(p),mid+1,r,L,R); } inline void change(int &p,int l,int r,int x,int w) { if(!p)p=++id; if(l==r)return sum(p)=w,void(); int mid=(l+r)>>1; if(x<=mid)change(l(p),l,mid,x,w); else change(r(p),mid+1,r,x,w); sum(p)=sum(l(p))+sum(r(p)); } inline int ask(int &p,int l,int r,int x) { if(!p)p=++id; if(l==r)return l; int mid=(l+r)>>1; if(mid-l+1-sum(l(p))>=x)return ask(l(p),l,mid,x); return ask(r(p),mid+1,r,x-(mid-l+1-sum(l(p)))); } int main() { //freopen("1.in","r",stdin); get(n);get(m); s1=1;s2=100000; s3=n+100001;s4=n+200000; modify(rt,1,s4,s1,s2); modify(rt,1,s4,s3,s4); rep(1,m,i) { int get(op),get(x)-ans; if(op==1) { int get(y)-ans; int ww=H.find(x); H.insert(y,ww); W.insert(ww,y); put(ans=(ww-ask(rt,1,s4,1,ww))); } if(op==2) { int ww=H.find(x); put(ans=(ww-ask(rt,1,s4,1,ww))); change(rt,1,s4,ww,1); change(rt,1,s4,s2,0); W.insert(s2,x); H.insert(x,s2);--s2; } if(op==3) { int ww=H.find(x); put(ans=(ww-ask(rt,1,s4,1,ww))); change(rt,1,s4,ww,1); change(rt,1,s4,s3,0); W.insert(s3,x); H.insert(x,s3);++s3; } if(op==4)put(ans=W.find1(ask(rt,1,s4,x))); } return 0; }