1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| #include<bits/stdc++.h> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std;
typedef long long LL;
const int maxn=1e5+5, maxq=5e5+5, MX=31;
int n,q,maxw,maxx,l[maxq],r[maxq],c[maxq]; LL s[maxn]; vector<pair<int,int>> v[MX+5];
int root[maxn],tot,son[maxn*40][2],num[maxn*40]; LL sum[maxn*40]; int New() { tot++; num[tot]=sum[tot]=son[tot][0]=son[tot][1]=0; return tot; } int tr_xg(int k,int last,int l,int r,int x) { while (l<r) { sum[k]=sum[last]+x, num[k]=num[last]+1; int t1=(l+r)>>1; if (x<=t1) { son[k][0]=New(); son[k][1]=son[last][1]; k=son[k][0], last=son[last][0], r=t1; } else { son[k][0]=son[last][0]; son[k][1]=New(); k=son[k][1], last=son[last][1], l=t1+1; } } sum[k]=sum[last]+x, num[k]=num[last]+1; } LL tr_cx(int k,int last,int l,int r,int x) { LL re=0; while (l<r) { int t1=(l+r)>>1; if (num[son[k][1]]-num[son[last][1]]>=x) k=son[k][1], last=son[last][1], l=t1+1; else { re+=sum[son[k][1]]-sum[son[last][1]]; x-=num[son[k][1]]-num[son[last][1]]; k=son[k][0], last=son[last][0], r=t1; } } return (x) ?re+(sum[k]-sum[last])/(num[k]-num[last])*x :re ; }
LL ans[maxq]; int main() { scanf("%d %d",&n,&q); fo(i,1,n) { scanf("%lld",&s[i]); maxx=(s[i]>maxx) ?s[i] :maxx ; int w=0; for(int x=s[i]; x; x>>=1) w++; maxw=max(maxw,w-1); for(int cnt=w-1, x=s[i]; x; cnt--, x>>=1) v[cnt].push_back(make_pair(i,x-(x>>1))); s[i]+=s[i-1]; } fo(i,1,q) { scanf("%d %d %d",&l[i],&r[i],&c[i]); ans[i]=s[r[i]]-s[l[i]-1]; } fd(i,maxw,0) { tot=-1; int last=New(); memset(root,0,sizeof(root)); for(auto p:v[i]) { tr_xg(root[p.first]=New(),last,1,maxx,p.second); last=root[p.first]; } fo(i,1,n) if (!root[i]) root[i]=root[i-1]; fo(j,1,q) if (c[j]) { int cnt=num[root[r[j]]]-num[root[l[j]-1]]; if (cnt>=c[j]) { ans[j]-=tr_cx(root[r[j]],root[l[j]-1],1,maxx,c[j]); c[j]=0; } else { c[j]-=cnt; ans[j]-=sum[root[r[j]]]-sum[root[l[j]-1]]; } } } fo(i,1,q) printf("%lld\n",ans[i]); }
|