【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

  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
",
 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
",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
",i);
104         out(1,1,n);puts("");
105         #endif
106     }
107     printf("%d
",ans);
108     return 0;
109 }
View Code