2019.7.10 義烏模擬賽 T3 C
阿新 • • 發佈:2021-07-10
一眼就感覺這個東西很APIO。
然後就真那道題的弱化版。
首先我們顯然處理出每個點往右邊跳能跳到哪裡出\(k\)
因為\(a\)非負所以這個東西顯然單調可以雙指標指出來。
然後發現我們得到的是一個樹形結構。於是愉快地樹上倍增即可。
時間複雜度\(O((m+n)logn)\)
code:
#include<bits/stdc++.h> #define I inline #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) #define abs(x) ((x)>0?(x):-(x)) #define re register #define ll long long #define db double #define N 1000000 #define M 30 #define mod 1000000007 #define eps (1e-7) #define U unsigned int #define IT set<ques>::iterator #define Gc() getchar() #define Me(x,y) memset(x,y,sizeof(x)) using namespace std; int n,m,x,y,now,A[N+5],Q[N+5],R[N+5],fa[N+5][25],lg[N+5],r=1,ans;ll Sum[N+5],k; I void read(int &x){ char s=getchar();x=0;while(s<'0'||s>'9') s=Gc(); while(s>='0'&&s<='9') x=x*10+s-48,s=Gc(); } I void print(int x){x>9&&(print(x/10),0);putchar(x%10+48);} int main(){ freopen("c.in","r",stdin);freopen("c.out","w",stdout); re int i,j;scanf("%d%d%lld",&n,&m,&k);for(i=1;i<=n;i++) read(A[i]),Sum[i]=Sum[i-1]+A[i],Q[i]=Q[i-1]+(A[i]>k); for(i=1;i<=n;i++){while(r<=n&&Sum[r]-Sum[i-1]<=k)r++;R[i]=(A[i]>k)?r:r-1;}for(i=2;i<=n;i++)lg[i]=lg[i/2]+1; for(i=n;i;i--){ for(fa[i][0]=R[i],j=1;fa[i][j-1];j++) fa[i][j]=fa[fa[i][j-1]+1][j-1]; } while(m--){ read(x);read(y);if(Q[y]-Q[x-1]>0){printf("Chtholly\n");continue;} ans=0;now=x;for(i=lg[n-x+1];~i;i--) if(fa[now][i]&&fa[now][i]<=y) ans+=(1<<i),now=fa[now][i]+1;print(ans+(now!=y+1)),putchar('\n'); } }