【CodeForces】【338E】Optimize!
线段树
先搞出来每个a[i]能连多少条边记为w[i]……如果对一组s[i],都满足w[i]-rank[i]>=0则这是一组合法方案,然后线段树维护w[i]-rank[i](第一个元素出去的时候后面所有的rank要-1,加入最后一个元素的时候后面的元素rank+1,建关于a[i]的权值线段树,记得离散化)
线段树维护的时候modify(区间修改)忘加push_down了……so sad
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<iostream> 5 #include<algorithm> 6 #define rep(i,n) for(int i=0;i<n;++i) 7 #define F(i,j,n) for(int i=j;i<=n;++i) 8 #define D(i,j,n) for(int i=j;i>=n;--i) 9 using namespace std; 10 typedef long long LL; 11 inline int getint(){ 12 int r=1,v=0; char ch=getchar(); 13 for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-1; 14 for(; isdigit(ch);ch=getchar()) v=v*10+ch-'0'; 15 return r*v; 16 } 17 const int N=200010,INF=~0u>>2; 18 //#define debug 19 /********************template*******************/ 20 struct node{ 21 int size,min,add; 22 }t[N<<2]; 23 #define L (o<<1) 24 #define R (o<<1|1) 25 #define mid (l+r>>1) 26 int n,m,len,H,w[N],a[N],b[N],c[N]; 27 void maintain(int o,int l,int r){ 28 if (l==r) return; 29 t[o].size=t[L].size+t[R].size; 30 if (t[o].size) t[o].min=min(t[L].min,t[R].min); 31 else t[o].min=INF,t[o].add=0; 32 } 33 int ql,qr; 34 void push_down(int o,int l,int r){ 35 if (!t[o].add) return; 36 t[L].add+=t[o].add; t[R].add+=t[o].add; 37 t[L].min+=t[o].add; t[R].min+=t[o].add;t[o].add=0; 38 } 39 void modify(int o,int l,int r,int num){ 40 if (ql>qr) return; 41 if (ql<=l && qr>=r) t[o].add+=num,t[o].min+=num; 42 else{ 43 push_down(o,l,r); 44 if (ql<=mid) modify(L,l,mid,num); 45 if (qr>mid ) modify(R,mid+1,r,num); 46 maintain(o,l,r); 47 } 48 } 49 void update(int o,int l,int r,int pos,int rank){ 50 if (l==r){ 51 t[o].size^=1; 52 t[o].min=t[o].size?w[pos]-rank-t[o].size:INF; 53 }else{ 54 push_down(o,l,r); 55 if (a[pos]<=mid) update(L,l,mid,pos,rank); 56 if (a[pos]>mid) update(R,mid+1,r,pos,rank+t[L].size); 57 maintain(o,l,r); 58 } 59 } 60 void out(int o,int l,int r){ 61 printf("%d %d %d %d %d %d\n", 62 o,l,r,t[o].size,t[o].add,t[o].min); 63 if (l==r) return; 64 else {out(L,l,mid); out(R,mid+1,r);} 65 } 66 inline bool cmp(int x,int y){return a[x]<a[y];} 67 int main(){ 68 #ifndef ONLINE_JUDGE 69 freopen("CF338E.in","r",stdin); 70 freopen("CF338E.out","w",stdout); 71 #endif 72 n=getint(); len=getint(); H=getint(); 73 F(i,1,len) b[i]=getint(); 74 sort(b+1,b+len+1);b[len+1]=INF; 75 F(i,1,n){ 76 c[i]=i; a[i]=getint(); 77 w[i]=len-(lower_bound(b+1,b+len+2,H-a[i])-b-1); 78 } 79 sort(c+1,c+n+1,cmp); 80 F(i,1,n) a[c[i]]=i; 81 F(i,1,n*4) t[i].min=INF; 82 F(i,1,len){ 83 ql=a[i]+1; qr=n; 84 modify(1,1,n,-1); 85 update(1,1,n,i,0); 86 } 87 88 #ifdef debug 89 F(i,1,n) printf("%d %d\n",a[i],w[i]); 90 out(1,1,n);puts(""); 91 #endif 92 int ans=t[1].min>=0; 93 F(i,len+1,n){ 94 ql=a[i-len]+1; qr=n; 95 update(1,1,n,i-len,0); 96 modify(1,1,n,1); 97 98 ql=a[i]+1; qr=n; 99 update(1,1,n,i,0); 100 modify(1,1,n,-1); 101 if (t[1].min>=0) ans++; 102 #ifdef debug 103 printf("%d\n",i); 104 out(1,1,n);puts(""); 105 #endif 106 } 107 printf("%d\n",ans); 108 return 0; 109 }