NC217863. 速度即转发
描述
BPM=RT
操作包含以下两种:
输入描述
第一行,两个正整数 。
第二行, 个非负整数 。
以下 行,每行第一个整数 表示操作的类型。若 ,则接下来有三个整数 ,表示一个查询速度操作。若 ,则接下来有两个整数 ,表示一个转发操作。
输出描述
对于每个查询操作,一行一个整数,表示答案。若在 内无解,输出 。
示例1
输入:
6 5 4 42 40 26 46 6 0 1 5 20 1 6 4 0 2 6 20 0 2 6 114514 0 1 6 0
输出:
36 36 -1 100000
C++(clang++11) 解法, 执行用时: 785ms, 内存消耗: 233184K, 提交时间: 2021-03-19 22:21:53
#include<iostream> #include<cstdio> #include<vector> using namespace std; #define N 100012 #define U 20000012 #define LL long long int n,m,tot=0,a[N],rt[N],c[U][2],s1[U];LL s[U]; inline void Ins(int &p,int l,int r,int v,int v1) { if(!p)p=++tot;s[p]+=v*v1;s1[p]+=v1;if(l==r)return;int mid=(l+r)>>1; (v<=mid)?Ins(c[p][0],l,mid,v,v1):Ins(c[p][1],mid+1,r,v,v1); } inline void Add(int x,int v,int v1){for(;x<=n;x+=x&(-x))Ins(rt[x],0,100000,v,v1);} vector<int>I,D;LL su=0;int sz=0; int Ask(int l,int r,LL k) { if(l==r)return l;int i,u,mid=(l+r)>>1,o;LL v=su-1ll*(mid+1)*sz; for(auto p:I)v+=s[c[p][1]]-1ll*(mid+1)*s1[c[p][1]];for(auto p:D)v-=s[c[p][1]]-1ll*(mid+1)*s1[c[p][1]]; if(v>=k){for(i=0,u=I.size();i<u;i++)I[i]=c[I[i]][1];for(i=0,u=D.size();i<u;i++)D[i]=c[D[i]][1];return Ask(mid+1,r,k);} for(i=0,u=I.size();i<u;i++)o=I[i],su+=s[c[o][1]],sz+=s1[c[o][1]],I[i]=c[o][0]; for(i=0,u=D.size();i<u;i++)o=D[i],su-=s[c[o][1]],sz-=s1[c[o][1]],D[i]=c[o][0];return Ask(l,mid,k); } int main(){ scanf("%d%d",&n,&m);int i,cm,x,v,l,r,ans;LL K; for(i=1;i<=n;i++){scanf("%d",&x);Add(i,x,1);a[i]=x;} while(m--) { scanf("%d",&cm); if(cm==0) { scanf("%d%d%lld",&l,&r,&K);I.clear();D.clear();su=0;sz=0; for(;r;r&=(r-1))I.push_back(rt[r]);for(--l;l;l&=(l-1))D.push_back(rt[l]);ans=Ask(0,100000,K); if(su<K)printf("-1\n");else printf("%d\n",ans); } else{scanf("%d%d",&x,&v);Add(x,a[x],-1),Add(x,a[x] = v,1);} }return 0; }