题解:P17738 [ICPC 2019 Xuzhou R] Yuuki and a problem
考察选手是否做过 P4587。
考虑怎么快速回答询问,我们可以对区间排序,从小到大处理和,不妨记当前和是
考虑加速这个过程,我们从
所以这样就可以做静态问题了,拿主席树维护值域,查询时两棵树作差,可以做到
但是有单点修改怎么办,不难发现这个询问其实是个
但是这太难写了,注意到时限比较松,直接拿带修莫队加分块维护这个东西,每次查询前缀和即可,复杂度
稍微卡一卡常数就跑进了 1s。
:::info[代码]
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define pr putchar(10)
#define fi first
#define se second
#define pp putchar(' ')
#define pii pair<ll,ll>
#define tri tuple<ll,ll,ll>
#define gt(k,x) (get<k>(x))
#define pdi pair<double,ll>
#define mem(aa,bb) memset(aa,bb,sizeof(aa))
#define fo(a,i,b) for(ll i = (a) ; i <= (b) ; ++ i )
#define Fo(a,i,b) for(ll i = (a) ; i >= (b) ; -- i )
#define pb push_back
#define reg register
#define eb emplace_back
#define bct __builtin_popcount
#define mk make_pair
#define IT iterator
#define all(x) x.begin(),x.end()
#define lbd lower_bound
#define ubd upper_bound
#define lowbit(x) ((x)&(-(x)))
#define gb(x,i) (((x)>>i)&1)
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define deb(a...) [&](auto...b){char s[]=" , ,"#a;strtok(s,",");((cerr<<strtok(0,",")<<"="<<b<<"; "),...)<<endl;}(__LINE__,a)
// #pragma GCC optimize("O3")
using namespace std;
bool ST;
typedef long long i64;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef unsigned long long ull;
typedef __int128 i128;
typedef __uint128_t u128;
typedef double db;
typedef int ll;
// typedef long long ll;
// typedef __int128 ll;
#define getchar getchar_unlocked
#define putchar putchar_unlocked
const ll mod=1e9+7;
template <class T> inline bool ckmn(T &a,T b){return a>b?a=b,1:0;}
template <class T> inline bool ckmx(T &a,T b){return a<b?a=b,1:0;}
template <class T> inline void _A(T &x,T y){x=(x+y>=mod?x+y-mod:x+y);}
template <class T> inline void _M(T &x,T y){x=1ll*x*y%mod;}
template <class T> inline T A_(T x,T y){return (x+y>=mod?x+y-mod:x+y);}
template <class T> inline T M_(T x,T y){return 1ll*x*y%mod;}
template <class T> inline void read(T &s)
{
s=0;reg int f=1;reg char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c))s=(s<<3)+(s<<1)+(c^48),c=getchar();s*=f;return;
}
template <class T> inline void wr(T x)
{
if(x<0)putchar('-'),x=-x;int buf[21],top=0;while(x)buf[++top]=x%10,x/=10;
if(!top)buf[++top]=0;while(top)putchar(buf[top--]^'0');return;
}
template <class T, class ...A> inline void read(T &x,A &...a){read(x);read(a...);}
template <class T, class ...A> inline bool ckmn(T &x,T y,A ...a){return ckmn(x,y)|ckmn(x,a...);}
template <class T, class ...A> inline bool ckmx(T &x,T y,A ...a){return ckmx(x,y)|ckmx(x,a...);}
template <class T, class ...A> inline void _A(T &x,T y,A ...a){_A(x,y),_A(x,a...);}
template <class T, class ...A> inline void _M(T &x,T y,A ...a){_M(x,y),_M(x,a...);}
template <class T, class ...A> inline T A_(T x,T y,A ...a){return A_(A_(x,y),a...);}
template <class T, class ...A> inline T M_(T x,T y,A ...a){return M_(M_(x,y),a...);}
const ll _N=1e6+5;ll Pre[_N],Inv[_N];
inline ll qpow(ll a,ll b){return !b?1ll:M_(1ll*qpow(M_(a,a),b>>1ll),((b&1ll)?a:1ll));}
inline ll C(ll n,ll m){return (n<m||n<0||m<0)?0ll:M_(Pre[n],Inv[m],Inv[n-m]);}
inline void InitC(ll n){Pre[0]=1;fo(1,i,n) Pre[i]=M_(Pre[i-1],i);Inv[n]=qpow(Pre[n],mod-2);Fo(n-1,i,1) Inv[i]=M_(Inv[i+1],(i+1));Inv[0]=1;}
const ll N=1e6+5,M=1e5+5;
ll n,q,op,l,r,a[N],L[N],R[N],bel[N];i64 res[N],resb[N],ans[N],cur;array<ll,2> _upd[N];vector<array<ll,3>> Q;
inline void upd(ll x,ll op){
if(op>0) res[x]+=x,resb[bel[x]]+=x,cur+=x;
else res[x]-=x,resb[bel[x]]-=x,cur-=x;
}
inline i64 pqry(ll k)
{
i64 ans=0;ll b=bel[k];
fo(1,i,b-1) ans+=resb[i];
fo(L[b],i,k) ans+=res[i];
return ans;
}
bool ED;
signed main(){
read(n,q);
ll m=0;fo(1,i,n) read(a[i]),ckmx(m,(ll)a[i]);
fo(1,i,q) read(op,l,r),
op==1?(_upd[i]={l,r},ckmx(m,(ll)r)):(Q.pb({l,r,i}),1);
ll _len=max(1,(ll)pow(n,2.0/3.0)),len=max(1,(ll)sqrt(m)),cnt=(m-1)/len+1;
fo(1,i,cnt) L[i]=R[i-1]+1,R[i]=L[i]+len-1;
ckmn(R[cnt],m);
fo(1,i,m) bel[i]=(i-1)/len+1;
sort(all(Q),[&](auto x,auto y)
{
return x[0]/_len==y[0]/_len?(x[1]/_len==y[1]/_len?x[2]<y[2]:x[1]/_len<y[1]/_len):x[0]/_len<y[0]/_len;
});
mem(ans,-1);ll _l=1,_r=0,_t=0;for(auto [l,r,id]:Q)
{
while(_r<r) upd(a[++_r],1);
while(_l>l) upd(a[--_l],1);
while(_r>r) upd(a[_r--],-1);
while(_l<l) upd(a[_l++],-1);
while(_t<id)
{
++_t;if(!_upd[_t][0]) continue;
if(_upd[_t][0]>=_l&&_upd[_t][0]<=_r)
upd(a[_upd[_t][0]],-1);
swap(a[_upd[_t][0]],_upd[_t][1]);
if(_upd[_t][0]>=_l&&_upd[_t][0]<=_r)
upd(a[_upd[_t][0]],1);
}
while(_t>id)
{
if(!_upd[_t][0]){--_t;continue;}
if(_upd[_t][0]>=_l&&_upd[_t][0]<=_r)
upd(a[_upd[_t][0]],-1);
swap(a[_upd[_t][0]],_upd[_t][1]);
if(_upd[_t][0]>=_l&&_upd[_t][0]<=_r)
upd(a[_upd[_t][0]],1);
--_t;
}
i64 nw=0;while(nw<cur){ll k=nw+1>m?m:(ll)(nw+1);i64 s=pqry(k);if(s==nw) break;nw=s;}
ans[id]=nw+1;
}fo(1,i,q) if(_upd[i][0]==0) wr(ans[i]),pr;
cerr << "Time: " << (double)clock()/CLOCKS_PER_SEC << "s\n";
cerr << "Memory: " << abs(&ST - &ED) / 1024.0 / 1024.0 << " MB\n";
return 0;
}
:::