题解 P1503 【鬼子进村】

wuzhoupei

2018-01-25 16:35:27

Solution

![Peipei](http://img.blog.csdn.net/20180120093509502?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcHJldGVuZF9mYWw=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 上面是我的 Logo >\_< ~~这个我不会用平衡树,线段树之类的搞~~ 我一开始想平衡树了,fhq Treap 但是我是真心没想到怎么操作 根据某白的话 >遇事不决先分块 所以 我用的分块啊 简单暴力 而且稳定O(nsqrt(n)) 超级棒 ```cpp #include <bits/stdc++.h> #define II int #define IL inline #define R register #define I 123456 using namespace std; IL void of(R II &a) { R char c=getchar(); R II w=1,p=0; while (c<'0' || c>'9') { if(c=='-') w=-1; c=getchar(); } while (c>='0' && c<='9') { p=p*10+c-'0'; c=getchar(); } a=p*w; } /* -------------------- Peipei -------------------- */ II Stack[I], had[I], lazy[I], belong[I]; II block,n,m,_top; IL II Ll(R II x) { R II ans=0; while (x>0 && !lazy[x/block]) ans+=min(x,block), x-=block; while (x>0 && !had[x]) ans++, x--; return ans; } IL II Rr(R II x) { R II ans=0; if(x==n+1) return 0; while (x<=n && !lazy[belong[x]]) ans+=block, x+=block; if(x>n+1) ans-=block-(n-n/block*block); while (x<=n && !had[x]) ans++, x++; return ans; } IL II todo(R II x) { R II ans=0,l=x,r=x,flag=0; if(had[x]) return 0; while (l && belong[l]==belong[x]) { ans++; l--; if(had[l]) { flag=1; break ; } } if(!flag) ans+=Ll(l); flag=0; r++; while (r<=n && belong[r]==belong[x]) { if(had[r]) { flag=1; break ; } ans++; r++; } if(!flag) ans+=Rr(r); return ans; } int main() { // freopen("1.in","r",stdin); of(n); of(m); block=sqrt(n); for(R II i=1;i<=n;i++) belong[i]=(i-1)/block+1; R char opt; R II x; while (m --) { cin>> opt; if(opt=='D') { of(x); Stack[++_top]=x; had[x]=1; lazy[belong[x]]++; } if(opt=='R') { x=Stack[_top--]; had[x]=0; lazy[belong[x]]--; } if(opt=='Q') { of(x); printf("%d\n",todo(x)); } } } ``` 根本不用去讲细节实现 裸的分块啦