专项测试(数据结构2)
专项测试(数据结构2)
不不不不不是数据结构,是煞笔题,是垃圾题
是给码不给题解的题
是摇摆兵不会的题
是\(pyt\)爆切\(T2\)的题
是我改不完的题
T1 学军题
不会
T2 CF571D
这个做法非常多,我是启发式合并+主席树
AC_code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*t;
}
const int N=1e5+5;
int n,m,a[N];
vector<int> s[N],t[N];
struct node{int id,p;};
vector<node> bs[N],bt[N];
vector<int> sim[N];
int ssz[N],tsz[N];
int is[N],it[N];
struct Q{int tp,x,y;}q[N*5];
int srt[N],trt[N];
struct sZXS{
struct POT{
int ls,rs;ll sum;
}tr[N*4*18];
int seg;
int newpot(int x){
++seg;tr[seg]=tr[x];
return seg;
}
void ins(int &x,int l,int r,int ql,int qr,int v){
x=newpot(x);
if(ql<=l&&r<=qr)return tr[x].sum+=v,void();
int mid=l+r>>1;
if(ql<=mid)ins(tr[x].ls,l,mid,ql,qr,v);
if(qr>mid)ins(tr[x].rs,mid+1,r,ql,qr,v);
}
ll query(int pr,int x,int l,int r,int pos){
if(l==r)return tr[x].sum-tr[pr].sum;
int mid=l+r>>1;
if(pos<=mid)return query(tr[pr].ls,tr[x].ls,l,mid,pos)+tr[x].sum-tr[pr].sum;
else return query(tr[pr].rs,tr[x].rs,mid+1,r,pos)+tr[x].sum-tr[pr].sum;
}
}sz;
struct tZXS{
struct POT{
int mx,ls,rs;
}tr[N*4*18];
int seg;
int newpot(int x){
++seg;tr[seg]=tr[x];
return seg;
}
void ins(int &x,int l,int r,int ql,int qr,int v){
if(!x)x=newpot(x);
if(ql<=l&&r<=qr)return tr[x].mx=v,void();
int mid=l+r>>1;
if(ql<=mid)ins(tr[x].ls,l,mid,ql,qr,v);
if(qr>mid)ins(tr[x].rs,mid+1,r,ql,qr,v);
}
int query(int x,int l,int r,int pos){
if(!x)return 0;
if(l==r)return tr[x].mx;
int mid=l+r>>1;
if(pos<=mid)return max(query(tr[x].ls,l,mid,pos),tr[x].mx);
else return max(query(tr[x].rs,mid+1,r,pos),tr[x].mx);
}
}tz;
signed main(){
n=read();m=read();
fo(i,1,n){
s[i].push_back(i);bs[i].push_back(node{i,0});
t[i].push_back(i);bt[i].push_back(node{i,0});
ssz[i]=1;tsz[i]=1;
}
fo(i,1,m){
char tp[5];scanf("%s",tp+1);
int x=read(),y;
if(tp[1]=='U'){
q[i].tp=1;q[i].x=x;q[i].y=y=read();
int nx=bs[x].rbegin()->id,ny=bs[y].rbegin()->id;
if(nx==ny)continue;
if(ssz[nx]>=ssz[ny]){
for(int i:s[ny]){
s[nx].push_back(i);
bs[i].push_back(node{nx,ssz[nx]});
ssz[nx]++;
}
}
else {
for(int i:s[nx]){
s[ny].push_back(i);
bs[i].push_back(node{ny,ssz[ny]});
ssz[ny]++;
}
}
}
if(tp[1]=='M'){
q[i].tp=2;q[i].x=x;q[i].y=y=read();
int nx=bt[x].rbegin()->id,ny=bt[y].rbegin()->id;
if(nx==ny)continue;
if(tsz[nx]>=tsz[ny]){
for(int i:t[ny]){
t[nx].push_back(i);
bt[i].push_back(node{nx,tsz[nx]});
tsz[nx]++;
}
}
else {
for(int i:t[nx]){
t[ny].push_back(i);
bt[i].push_back(node{ny,tsz[ny]});
tsz[ny]++;
}
}
}
if(tp[1]=='A'){
q[i].tp=3;q[i].x=x;
}
if(tp[1]=='Z'){
q[i].tp=4;q[i].x=x;
}
if(tp[1]=='Q'){
q[i].tp=5;q[i].x=x;
}
}
fo(i,1,n){
ssz[i]=tsz[i]=1;
is[i]=it[i]=0;
sim[i].push_back(0);
}
fo(mm,1,m){
int tp=q[mm].tp,x=q[mm].x,y=q[mm].y;
if(tp==1){
int nx=bs[x][is[x]].id,ny=bs[y][is[y]].id;
if(nx==ny)continue;
if(ssz[nx]>=ssz[ny]){
for(int i:s[ny])is[i]++;
ssz[nx]+=ssz[ny];
}
else {
for(int i:s[nx])is[i]++;
ssz[ny]+=ssz[nx];
}
}
if(tp==2){
int nx=bt[x][it[x]].id,ny=bt[y][it[y]].id;
if(nx==ny)continue;
if(tsz[nx]>=tsz[ny]){
for(int i:t[ny])it[i]++;
tsz[nx]+=tsz[ny];
}
else {
for(int i:t[nx])it[i]++;
tsz[ny]+=tsz[nx];
}
}
if(tp==3){
int nx=bs[x][is[x]].id;
int lst=*sim[nx].rbegin();
sim[nx].push_back(mm);srt[mm]=srt[lst];
int R=s[nx].size()-1;
sz.ins(srt[mm],0,R,0,ssz[nx]-1,ssz[nx]);
}
if(tp==4){
int nx=bt[x][it[x]].id;
int R=t[nx].size()-1;
tz.ins(trt[nx],0,R,0,tsz[nx]-1,mm);
}
if(tp==5){
int lim=0;ll ans=0;
for(node i:bt[x]){
int nx=i.id;
int R=t[nx].size()-1;
lim=max(lim,tz.query(trt[nx],0,R,i.p));
if(i.id==bt[x][it[x]].id)break;
}
for(node i:bs[x]){
int nx=i.id;
int R=s[nx].size()-1;
vector<int>::iterator pos=upper_bound(sim[nx].begin(),sim[nx].end(),lim);
if(pos!=sim[nx].end()){
ans+=sz.query(srt[*prev(pos)],srt[*sim[nx].rbegin()],0,R,i.p);
}
if(i.id==bs[x][is[x]].id)break;
}
printf("%lld\n",ans);
}
}
return 0;
}
T3 counting on tree
这个直接斜率优化,用\(set\)维护凸包,因为横坐标无序
AC_code
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*t;
}
const int inf=0x3f3f3f3f3f3f3f3f;
const int N=1e6+5;
int n,a[N],ans;
int fa[N],sum[N],son[N];
int to[N],nxt[N],head[N],rp;
void add_edg(int x,int y){
to[++rp]=y;
nxt[rp]=head[x];
head[x]=rp;
}
int dp[N],tg[N];
struct node{
int x,y;
bool operator < (node a)const{return x<a.x;}
};
double k(node a,node b){return 1.0*(a.y-b.y)/(a.x-b.x);}
bool comp(node a,node b,node c){return k(a,b)<k(b,c);}
int pw(int x){return x*x;}
set<node> s[N];
void ins(int x,node v){
v.y-=tg[x];
set<node>::iterator it=s[x].lower_bound(v);
if(it!=s[x].end()&&it->x==v.x){
if(it->y<=v.y)return ;
else s[x].erase(it);
}
while(!s[x].empty()){
set<node>::iterator i=s[x].lower_bound(v);
if(i==s[x].begin())break;
i--;if(i==s[x].begin())break;
set<node>::iterator j=prev(i);
if(!comp(*j,*i,v))s[x].erase(i);
else break;
}
while(!s[x].empty()){
set<node>::iterator i=s[x].lower_bound(v);
if(i==s[x].end())break;
set<node>::iterator j=next(i);
if(j==s[x].end())break;
if(!comp(v,*i,*j))s[x].erase(i);
else break;
}
set<node>::iterator i=s[x].lower_bound(v);
if(i==s[x].begin()||i==s[x].end())return s[x].insert(v),void();
set<node>::iterator j=prev(i);
if(comp(*j,v,*i))s[x].insert(v);
}
int get(int x){
if(s[x].empty())return inf;
node ret;
if(s[x].size()==1)ret=*s[x].begin();
else {
int l=s[x].begin()->x,r=s[x].rbegin()->x,mid;
while(l<r){
mid=l+r+1>>1;
set<node>::iterator it=s[x].lower_bound(node{mid,-inf});
if(it==s[x].begin()){l=mid;continue;}
node i=*prev(it),j=*it;
i.y+=tg[x];j.y+=tg[x];
if(k(i,j)>=2*sum[fa[x]])r=mid-1;
else l=mid;
}
ret=*s[x].lower_bound(node{l,-inf});
}
ret.y+=tg[x];
return pw(sum[fa[x]])-2*sum[fa[x]]*ret.x+ret.y;
}
void dfs(int x){
sum[x]=sum[fa[x]]+a[x];int mx=0;
for(int i=head[x];i;i=nxt[i]){
dfs(to[i]);son[x]+=dp[to[i]];
if(s[to[i]].size()>s[mx].size())mx=to[i];
}
swap(s[x],s[mx]);tg[x]=tg[mx]+son[x]-dp[mx];
for(int i=head[x];i;i=nxt[i]){
if(to[i]==mx)continue;
tg[to[i]]+=son[x]-dp[to[i]];
for(node j:s[to[i]])j.y+=tg[to[i]],ins(x,j);
}
dp[x]=min(get(x),son[x]+pw(a[x]));
ins(x,node{sum[x],son[x]+pw(sum[x])});
}
signed main(){
n=read();
fo(i,1,n)a[i]=read();
fo(i,2,n)fa[i]=read(),add_edg(fa[i],i);
dfs(1);printf("%lld",dp[1]);
return 0;
}
QQ:2953174821