计蒜客NOIP2017提高组模拟赛(五)day2-蚂蚁搬家

传送门

这题可以用线段树来维护

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<map>
  7 #include<set>
  8 #include<queue>
  9 #include<vector>
 10 #define INF 0x7f7f7f7f
 11 #define pii pair<int,int>
 12 #define ll long long
 13 #define MAXN 500005
 14 #define DEBUG 1
 15 using namespace std;
 16 int read(){
 17     int x=0,f=1;char ch=getchar();
 18     while(ch<'0'||ch>'9'){if('-'==ch)f=-1;ch=getchar();}
 19     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 20     return x*f;
 21 }
 22 int n,T;
 23 int a[MAXN];
 24 int dat[MAXN*4];
 25 void build(int k,int L,int R){
 26     if(L+1==R){
 27         dat[k]=a[L];
 28         return;
 29     }
 30     build(k<<1,L,(L+R)>>1);
 31     build(k<<1|1,(L+R)>>1,R);
 32     dat[k]=max(dat[k<<1],dat[k<<1|1]);
 33 }
 34 void change(int a,int k,int L,int R,int x){
 35     if(L+1==R){
 36         dat[k]-=x;
 37         return;
 38     }
 39     int mid=(L+R)/2;
 40     if(a<mid){
 41         change(a,k<<1,L,mid,x);
 42     }
 43     else{
 44         change(a,k<<1|1,mid,R,x);
 45     }
 46     dat[k]=max(dat[k<<1],dat[k<<1|1]);
 47 }
 48 int ask(int a,int k,int L,int R){
 49     if(L+1==R){
 50         return dat[k];
 51     }
 52     int mid=(L+R)/2;
 53     if(a<mid){
 54         return ask(a,k<<1,L,mid);
 55     }
 56     else{
 57         return ask(a,k<<1|1,mid,R);
 58     }
 59 }
 60 int Lfind(int a,int b,int k,int L,int R,int x){
 61     if(b<=L||R<=a||dat[k]<x){
 62         return -1;
 63     }
 64     if(L+1==R){
 65         return L;
 66     }
 67     int t=Lfind(a,b,k<<1|1,(L+R)>>1,R,x);
 68     if(t!=-1){
 69         return t;
 70     }
 71     t=Lfind(a,b,k<<1,L,(L+R)>>1,x);
 72     return t;
 73 }
 74 int Rfind(int a,int b,int k,int L,int R,int x){
 75     if(b<=L||R<=a||dat[k]<x){
 76         return -1;
 77     }
 78     if(L+1==R){
 79         return L;
 80     }
 81     int t=Rfind(a,b,k<<1,L,(L+R)>>1,x);
 82     if(t!=-1){
 83         return t;
 84     }
 85     t=Rfind(a,b,k<<1|1,(L+R)>>1,R,x);
 86     return t;
 87 }
 88 void init(){
 89     n=read();T=read();
 90     for(int i=1;i<=n;i++){
 91         a[i]=read();
 92     }
 93     build(1,1,n+1);
 94 }
 95 void debug(int k,int L,int R){
 96     if(L+1==R){
 97         printf("%d ",dat[k]);
 98         return;
 99     }
100     debug(k<<1,L,(L+R)>>1);
101     debug(k<<1|1,(L+R)>>1,R);    
102 }
103 void solve(){
104     for(int i=1;i<=T;i++){
105 //        debug(1,1,n+1);
106 //        printf("\n");
107         int x=read(),y=read();
108         if(dat[1]<x){
109             printf("-1\n");
110             continue;
111         }
112         if(ask(y,1,1,n+1)>=x){
113             change(y,1,1,n+1,x);
114             printf("%d\n",y);
115             continue;
116         }
117         int tL=Lfind(1,y-1+1,1,1,n+1,x);
118         int tR=Rfind(y+1,n+1,1,1,n+1,x);
119         if(-1==tL||-1==tR){
120             tR=(tL==-1?tR:tL);
121         }
122         else if(y-tL<=tR-y){
123             tR=tL;
124         }
125         change(tR,1,1,n+1,x);
126         printf("%d\n",tR);
127     }
128 //    debug(1,1,n+1);
129 //    printf("\n");
130 }
131 int main()
132 {
133 //    freopen("data.in","r",stdin);
134 //    freopen("my.out","w",stdout);
135     init();
136     solve();
137     return 0;
138 }

 

posted @ 2017-10-30 18:46  white_hat_hacker  阅读(197)  评论(0编辑  收藏  举报