社区讨论
我好不容易学会树上莫队,你却让我WA得这么彻底
P4074[WC2013] 糖果公园参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lwqae9yq
- 此快照首次捕获于
- 2024/05/28 19:01 2 年前
- 此快照最后确认于
- 2024/05/28 20:38 2 年前
rt,40pts,求活雷锋帮条QAQ。
CPP#include<bits/stdc++.h>
#define int long long
#define pos(x) (x/qn+bool(x%qn))
using namespace std;
const int cxk=4e5+5;
vector<int>nbr[cxk];
int n,m,qn,k,tot,ans,w[cxk],v[cxk],to[cxk],num[cxk],cnt[cxk],c[cxk],dp[cxk][22],dep[cxk],in[cxk],out[cxk];
struct ikun
{
int lt,rt,t,l,i;
friend bool operator<(const ikun&x,const ikun&y)
{
if(pos(x.lt)!=pos(y.lt))
return pos(x.lt)<pos(y.lt);
if(pos(x.rt)!=pos(y.rt))
return pos(x.rt)<pos(y.rt);
return pos(x.t)<pos(y.t);
}
}q[cxk];
pair<int,int>p[cxk];
bool vis[cxk];
void dfs(int cur,int fa)
{
dp[cur][0]=fa;
for(int i=1;i<=21;i++)
dp[cur][i]=dp[dp[cur][i-1]][i-1];
dep[cur]=dep[fa]+1;
to[in[cur]=++tot]=cur;
for(int nxt:nbr[cur])
{
if(nxt==fa)
continue;
dfs(nxt,cur);
}
to[out[cur]=++tot]=cur;
}
int lca(int x,int y)
{
if(dep[x]<dep[y])
swap(x,y);
for(int i=21;i>=0;i--)
if(dep[dp[x][i]]>=dep[y])
x=dp[x][i];
if(x==y)
return x;
for(int i=21;i>=0;i--)
if(dp[x][i]!=dp[y][i])
{
x=dp[x][i];
y=dp[y][i];
}
return dp[x][0];
}
void insert(int x)
{
vis[to[x]]^=1;
if(vis[to[x]])
{
cnt[c[x]]++;
ans+=w[cnt[c[x]]]*v[c[x]];
}
else
{
ans-=w[cnt[c[x]]]*v[c[x]];
cnt[c[x]]--;
}
}
//void erase(int x)本质上和insert一样
//{
// if(vis[to[x]]==0)
// ans+=w[++cnt[c[x]]]*v[c[x]];
// else
// ans-=w[cnt[c[x]]--]*v[c[x]];
// vis[to[x]]^=1;
//}
void takes(int lt,int rt,int t)
{
int x=p[t].first,&y=p[t].second;
if(lt<=x&&x<=rt)
if(vis[to[x]])
{
ans-=w[cnt[c[x]]--]*v[c[x]];
ans+=w[++cnt[y]]*v[y];
}
else
{
ans+=w[++cnt[c[x]]]*v[c[x]];
ans-=w[cnt[y]--]*v[y];
}
swap(c[x],y);
}
signed main()
{
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>m>>k;
qn=sqrt(2*n);
for(int i=1;i<=m;i++)
cin>>v[i];
for(int i=1;i<=n;i++)
cin>>w[i];
for(int i=1,x,y;i<n;i++)
{
cin>>x>>y;
nbr[x].push_back(y);
nbr[y].push_back(x);
}
dfs(1,0);
for(int i=1;i<=n;i++)
{
cin>>c[in[i]];
c[out[i]]=c[in[i]];
}
int s1=0,s2=0;
for(int i=1,opt,x,y,l;i<=k;i++)
{
cin>>opt>>x>>y;
if(opt==0)
{
p[++s1]={in[x],y};
p[++s1]={out[x],y};
}
else
{
if(in[x]>in[y])
swap(x,y);
l=lca(x,y);
s2++;
if(l==x)
q[s2]={in[x],in[y],s1,0,s2};
else
q[s2]={out[x],in[y],s1,in[l],s2};
}
}
sort(q+1,q+s2+1);
for(int i=1,lt=1,rt=0,t=0;i<=s2;i++)
{
int x=q[i].lt,y=q[i].rt,z=q[i].t;
while(rt<y)
insert(++rt);
while(y<rt)
insert(rt--);
while(lt<x)
insert(lt++);
while(x<lt)
insert(--lt);
while(t<z)
takes(lt,rt,++t);
while(z<t)
takes(lt,rt,t--);
num[q[i].i]=ans;
if(q[i].l)
num[q[i].i]+=w[cnt[c[q[i].l]]+1]*v[c[q[i].l]];
}
for(int i=1;i<=s2;i++)
cout<<num[i]<<"\n";
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...