维护区间加和区间第k小。
n<=100000
分块,设块大小为k相信大家都会O(n/k log^2 n)的查询和O(k)的修改。
什么你不会O(k)的修改?归并啊归并啊。
那么平衡规划一下k= n√logn
总复杂度 O(nn√logn)
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a) for(int i=lst[a];i;i=nxt[i])
using namespace std;
int read() {
char ch;
for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
int x=ch-'0';
for(ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x;
}
void write(int x) {
if (!x) {puts("0");return;}
if (x<0) {putchar('-');x=-x;}
char ch[20];int tot=0;
for(;x;x/=10) ch[++tot]=x%10+'0';
fd(i,tot,1) putchar(ch[i]);
puts("");
}
const int N=5*1e5+5,M=100;
int t[N],val[N],nxt[N],lst[N],num;
void add(int x,int y,int z) {
t[++num]=y;val[num]=z;nxt[num]=lst[x];lst[x]=num;
}
struct P{int v,w;}a[N],b[N],c[N];
bool cmp(P x,P y) {return x.v<y.v;}
int dfn[N],size[N],tot,n,m;
void dfs(int x,int y,int z) {
dfn[x]=++tot;a[tot].v=z;a[tot].w=tot;size[x]=1;
rep(i,x) if (t[i]!=y) {dfs(t[i],x,z+val[i]);size[x]+=size[t[i]];}
}
int bl[N],L[N],R[N],lazy[N],Sz;
int find(int w) {fo(i,1,Sz) if (L[i]<=w&&w<=R[i]) return i;}
int p[N],q[N];
bool bz[N];
void rebuild(int v,int l,int r,int k) {
fo(i,L[v],R[v]) bz[i]=0;
fo(i,l,r) a[i].v+=k,bz[a[i].w]=1;
q[0]=p[0]=0;
fo(i,L[v],R[v])
if (bz[i]) q[++q[0]]=i;
else p[++p[0]]=i;
int i=1,j=1,cnt=0;
while (i<=q[0]&&j<=p[0]) {
if (b[q[i]].v+kq[i++]];c[cnt].v+=k;}
else c[++cnt]=b[p[j++]];
}
while (i<=q[0]) {c[++cnt]=b[q[i++]];c[cnt].v+=k;}
while (j<=p[0]) c[++cnt]=b[p[j++]];
fo(i,1,cnt) b[L[v]+i-1]=c[i];
fo(i,L[v],R[v]) a[b[i].w].w=i;
}
int len,opt,x,k,z,l,r,u,v;
int solve(int u,int l,int r,int v) {
int cnt=0;
fo(i,l,r) if (a[i].v+lazy[u]<=v) cnt++;
return cnt;
}
int query(int u,int v) {
int l=L[u],r=R[u]+1;
while (lint mid=l+r>>1;
if (b[mid].v+lazy[u]<=v) l=mid+1;
else r=mid;
}
return l-L[u];
}
int check(int mid) {
int res=0;
if (u==v) return solve(u,l,r,mid);
res=solve(u,l,R[u],mid)+solve(v,L[v],r,mid);
fo(i,u+1,v-1) res+=query(i,mid);
return res;
}
int main() {
//freopen("yuno.in","r",stdin);
//freopen("yuno.out","w",stdout);
n=read();m=read();len=read();
fo(i,2,n) {
x=read();z=read();
add(x,i,z);
}
dfs(1,0,0);
fo(i,1,n) bl[i]=(i-1)/M+1;Sz=bl[n];
fo(i,1,Sz) L[i]=R[i-1]+1,R[i]=min(L[i]+M-1,n);
fo(i,1,Sz) {
fo(j,L[i],R[i]) b[j]=a[j];
sort(b+L[i],b+R[i]+1,cmp);
fo(j,L[i],R[i]) a[b[j].w].w=j;
}
for(;m;m--) {
opt=read();x=read();k=read();
l=dfn[x];r=dfn[x]+size[x]-1;
u=find(l);v=find(r);
if (opt==1) {
if (k>size[x]) {write(-1);continue;}
int le=0,ri=(n+m)*10;
while (leint mid=le+ri>>1;
if (check(mid)>=k) ri=mid;
else le=mid+1;
}
write(le);
} else {
if (u==v) {rebuild(u,l,r,k);continue;}
fo(i,u+1,v-1) lazy[i]+=k;
rebuild(u,l,R[u],k);rebuild(v,L[v],r,k);
}
}
return 0;
}
UPD:找到错了,原来是我本来开了一个全局变量结果却手贱int了它
然后我TLE了,由乃题日常结局