题解:P10559 [ICPC2024 Xi'an I] The Last Cumulonimbus Cloud
Larunatrecy · · 题解
不考虑题目保证的性质,本题是个经典的图上邻域问题,有众所周知的根号分治
考虑这个做法的本质:给每条边定向,维护每个点
在本题中,容易证明可以存在一种每次删掉度数不超过
更进一步,我们可以离线下来,求出每个点被询问/修改的总次数,每条边定向为这个次数更小的一边,可以证明这个的操作次数是不超过
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+7;
const int M = 3e6+7;
int n,m,q;
int u[M],v[M],sum[N],cnt[N];
int a[N],qc[M],qx[M],qv[M];
vector<int> T[N];
struct IO{
static const int S=1<<21;
char buf[S],*p1,*p2;int st[105],Top;
~IO(){clear();}
inline void clear(){fwrite(buf,1,Top,stdout);Top=0;}
inline void pc(const char c){Top==S&&(clear(),0);buf[Top++]=c;}
inline char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
inline IO&operator >> (char&x){while(x=gc(),x==' '||x=='\n'||x=='\r');return *this;}
template<typename T>inline IO&operator >> (T&x){
x=0;bool f=0;char ch=gc();
while(!isdigit(ch)){if(ch=='-') f^=1;ch=gc();}
while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=gc();
f?x=-x:0;return *this;
}
inline IO&operator << (const char c){pc(c);return *this;}
template<typename T>inline IO&operator << (T x){
if(x<0) pc('-'),x=-x;
do{st[++st[0]]=x%10,x/=10;}while(x);
while(st[0]) pc('0'+st[st[0]--]);return *this;
}
}fin,fout;
int main()
{
fin>>n>>m>>q;
for(int i=1;i<=m;i++)fin>>u[i]>>v[i];
for(int i=1;i<=n;i++)fin>>a[i];
for(int i=1;i<=q;i++)
{
fin>>qc[i]>>qx[i];
if(qc[i]==1)fin>>qv[i];
cnt[qx[i]]++;
}
for(int i=1;i<=m;i++)
{
if(cnt[u[i]]>cnt[v[i]])swap(u[i],v[i]);
T[u[i]].push_back(v[i]);
sum[v[i]]+=a[u[i]];
}
for(int i=1;i<=q;i++)
{
int x=qx[i];
if(qc[i]==1)
{
a[x]+=qv[i];
for(int y:T[x])sum[y]+=qv[i];
}
else
{
int res=sum[x];
for(int y:T[x])res+=a[y];
fout<<res;
fout.pc('\n');
}
}
return 0;
}