2 条题解
-
0
贡献是 的若干次方要你做的事就很明显。
也就是最小化数列所有位置总和。
先考虑 递增怎么做。
由于限制永远是 ,故维护数列呈不增序列一定不劣,相当于若干个段一个个从后往前合并。
现在 不递增。
手玩一下发现可以把这个限制后面不在此限制中的位置挖到前面来,可以减少一些花费。
对于限制内的位置做法没有变。
对于限制后面的位置由于数列的不增性多挖肯定不优,我们也能够知道最多挖多少个过去,且肯定是尽量挖大的过去。
这里使用了极其丑陋的珂朵莉树+线段树的做法,不推荐学习,二者实现的部分应该都可以用同一个数据结构同时实现。我更倾向于用珂树因为
珂朵莉很可爱题目中涉及非常多的连续段合并和修改。每次询问至多为序列新增 个连续段,若我们需要重复对序列操作则每次都会合并两个段,容易分析出复杂度为带有巨大常数的 ,但可以通过此题。
#include <bits/stdc++.h> #define lint __int128 #define int long long #define fi first #define se second #define Il inline #define vec vector #define pb push_back #define IT ::iterator #define p_q priority_queue using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; typedef double db; const int N=1e6,mod=1e9+7,Inf=1e18; const db eps=1e-9,pi=acos(-1.0); // bool P1; Il int qpow(int x,int y){ int t=1ll; for(;y;y>>=1ll,x=x*x%mod){ if(y&1ll){ t=t*x%mod; } } return t; } Il int F(int x){ return x?qpow(3,x-1):0ll; } int Q; int sm[(N<<2)+5],tg[(N<<2)+5],ss[(N<<2)+5],Tg[(N<<2)+5]; struct Cho{ int l,r,le;mutable int va; Il bool operator <(const Cho &s)const{ return l^s.l?l<s.l:r<s.r; } }; set<Cho>odt; Il set<Cho>IT split(int ps){ set<Cho>IT it=odt.lower_bound({ps,-1,-1,-1}); if(it!=odt.end()&&it->l==ps)return it; it--; if((it->r)<ps)return odt.end(); int tl=it->l,tr=it->r,tv=it->va; odt.erase(it),odt.insert({tl,ps-1,ps-tl,tv}); return odt.insert({ps,tr,tr-ps+1,tv}).fi; } Il set<Cho>IT meg(int l,int r,int x){ set<Cho>IT ir=split(r+1),il=split(l);odt.erase(il,ir); return odt.insert({l,r,r-l+1,x}).fi; } Il void pown(int p,int l,int r){ if(tg[p]<0)return; int mid=(l+r)>>1; ss[p<<1]=tg[p]*(mid-l+1),ss[p<<1|1]=tg[p]*(r-mid); sm[p<<1]=Tg[p]*(mid-l+1)%mod,sm[p<<1|1]=Tg[p]*(r-mid)%mod; tg[p<<1]=tg[p<<1|1]=tg[p],Tg[p<<1]=Tg[p<<1|1]=Tg[p],tg[p]=Tg[p]=-1; return; } Il void cov(int ql,int qr,int l,int r,int p,int x,int y){ if(ql<=l&&r<=qr){ ss[p]=(r-l+1)*x,sm[p]=(r-l+1)*y%mod,tg[p]=x,Tg[p]=y; return; } int mid=(l+r)>>1;pown(p,l,r); if(ql<=mid){ cov(ql,qr,l,mid,p<<1,x,y); } if(qr>mid){ cov(ql,qr,mid+1,r,p<<1|1,x,y); } sm[p]=(sm[p<<1]+sm[p<<1|1])%mod,ss[p]=ss[p<<1]+ss[p<<1|1]; return; } Il int qsm(int ql,int qr,int l,int r,int p){ if(ql<=l&&r<=qr)return ss[p]; int mid=(l+r)>>1,t=0;pown(p,l,r); if(ql<=mid){ t+=qsm(ql,qr,l,mid,p<<1); } if(qr>mid){ t+=qsm(ql,qr,mid+1,r,p<<1|1); } return t; } Il void chg(set<Cho>IT it,bool ff){ if(ff){ cov(it->l,it->r,1,N,1,it->va,F(it->va)); }else{ cov(it->l,it->r,1,N,1,0,0); } return; } // bool P2; signed main(){ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); // cout<<abs((&P1)-(&P2))/1024/1024;return 0; for(int i=0;i<=(N<<2);i++){ tg[i]=-1; } cin>>Q,odt.insert({1,N,N,0}); while(Q--){ int p,x;cin>>p>>x,x-=qsm(1,p,1,N,1);int cnt=x; if(p<N){ while(cnt>0){ set<Cho>IT it=split(p+1);int l=it->l,r=it->r,va=it->va,le=it->le; if(!va)break; if(r==N){ chg(it,0); if(va*le<=cnt){ it->va=0; break; } if(cnt%le){ int t=cnt/le,tt=cnt%le;set<Cho>IT It=split((it->r)-tt+1); It->va-=t+1,chg(It,1); It--,It->va-=t,chg(It,1); }else{ it->va-=cnt/le,chg(it,1); } break; }else{ set<Cho>IT It=it;It++;int dt=va-(It->va); if(dt*le<=cnt){ chg(it,0),chg(It,0); it=meg(l,It->r,It->va),chg(it,1),cnt-=dt*le; continue; } if(cnt%le){ int t=cnt/le,tt=cnt%le;it=split((it->r)-tt+1); chg(it,0),it->va-=t+1,chg(it,1),it--; chg(it,0),it->va-=t,chg(it,1); }else{ chg(it,0),it->va-=cnt/le,chg(it,1); } break; } } } while(x>0){ set<Cho>IT it=split(p+1);it--;int l=it->l,r=it->r,va=it->va,le=it->le; if(l==1){ chg(it,0); if(x%le){ int t=x/le,tt=x%le;set<Cho>IT It=split(tt+1); It->va+=t,chg(It,1),It--; It->va+=t+1,chg(It,1); }else{ it->va+=x/le,chg(it,1); } break; }else{ set<Cho>IT It=it;It--;int dt=(It->va)-va; if(dt*le<=x){ chg(it,0),chg(It,0); it=meg(It->l,r,It->va),chg(it,1),x-=dt*le; continue; } if(x%le){ int t=x/le,tt=x%le;it=split(l+tt); chg(it,0),it->va+=t,chg(it,1),it--; chg(it,0),it->va+=t+1,chg(it,1); }else{ chg(it,0),it->va+=x/le,chg(it,1); } break; } } cout<<sm[1]<<'\n'; } return 0; } -
0
#include<bits/stdc++.h> #define lc x<<1 #define rc x<<1^1 //#define int long long //#define int auto const int mod=1e9+7; const int N=1e6+5; const int Z=1e6; using namespace std; int n,m,ans,cnt,L,R; long long b; long long laz[N<<3]; long long g[N]={1},f[N]={1}; int rm; struct node{ int l,r; long long ans,s; }tr[N<<3]; bool fl=0,fl2=0; long long p(long long p){ if(!p) return 0; p--; long long v=1ll*g[p/Z]*f[p%Z]%mod; return v; } void built(int x,int l,int r){ tr[x].l=l; tr[x].r=r; if(l==r)return ; int mid=l+r>>1; built(lc,l,mid); built(rc,mid+1,r); } void ff(int x){if(x>=(N<<2))return ;tr[x].s=(tr[x].r-tr[x].l+1)*laz[x];tr[x].ans=(tr[x].r-tr[x].l+1)*p(laz[x]);tr[x].ans%=mod;} void pushdown(int x){if(x>=(N<<2))return ;if(laz[x]<0)return ;laz[lc]=laz[rc]=laz[x];ff(lc);ff(rc);laz[x]=-1;return ;} long long q(int x,int l,int r){if(r<l)return 0;if(tr[x].l>r||tr[x].r<l)return 0;pushdown(x);if(l<=tr[x].l&&tr[x].r<=r)return tr[x].s;return q(lc,l,r)+q(rc,l,r);} long long getans(int x,int l,int r){if(x>=(N<<2))return 0;if(tr[x].l>r||tr[x].r<l)return 0;pushdown(x);if(l<=tr[x].l&&tr[x].r<=r)return tr[x].ans;return (getans(lc,l,r)+getans(rc,l,r))%mod;} void ch(int x,int l,int r,long long s){if(r<l)return ;if(x>=(N<<2))return;if(tr[x].l>r||tr[x].r<l)return;if(l<=tr[x].l&&tr[x].r<=r){laz[x]=s;ff(x);return;}pushdown(x);ch(lc,l,r,s);ch(rc,l,r,s);tr[x].s=tr[lc].s+tr[rc].s;tr[x].ans=tr[lc].ans+tr[rc].ans;tr[x].ans%=mod;} int mxb=0; long long qo(int x,int p){if(x>=(N<<2))return 0;if(!p)return 1e12;if(tr[x].l>p||tr[x].r<p)return 0;pushdown(x);if(tr[x].l==tr[x].r)return tr[x].s;;return qo(lc,p)+qo(rc,p);} void work(){ long long x=q(1,1,m); if(x>=b){cout<<tr[1].ans%mod<<"\n";return;} long long c;int p;int l=1,r=m; while(l<=r){int mid=l+r>>1;c=qo(1,mid-1);if(q(1,1,mid-1)+(long long)(m-mid+1)*c>=b){l=mid+1;p=mid;}else r=mid-1;} long long w=b-x;b-=q(1,1,p-1);long long v=b/(m-p+1);int ls=b%(m-p+1);ch(1,p+ls,m,v);ch(1,p,p+ls-1,v+1); if(q(1,m+1,N)>w){l=m+1,r=N;while(l<=r){int mid=l+r>>1;long long c=qo(1,mid+1);if(q(1,m+1,mid)-c*(long long)(mid-m)>=(w)){p=mid;r=mid-1;}else l=mid+1;}b=q(1,m+1,p);b-=w;if(p==m){puts("E");exit(0);}v=b/(p-m);ls=b%(p-m);ch(1,m+ls+1,p,v);ch(1,m+1,m+ls,v+1);} else ch(1,m+!m,rm,0);cout<<tr[1].ans%mod<<"\n"; } signed main(){ // freopen("6.in","r",stdin); //freopen("1.out","w",stdout); for(int i=1;i<=Z;++i)f[i]=1ll*f[i-1]*3%mod;for(int i=1;i<=Z;++i)g[i]=1ll*g[i-1]*f[Z]%mod;cin>>n;memset(laz,-1,sizeof(laz));built(1,1,1000000);for(int i=1;i<=n;i++);for(int i=1;i<=n;i++){scanf("%d %lld",&m,&b);rm=max(rm,m);work();} }
- 1
信息
- ID
- 7610
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 38
- 已通过
- 4
- 上传者