详见代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=2e5+10;int h[N],e[N<<1],ne[N<<1],idx=0;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;return ;}
int n,m,q;
int cham[N],bs[N],big[N],in[N],id[N],ans[N];
vector<int>c[N];//存附近的大点 ;
vector<int>B[550][11000];//存大点附近的小点; int main()
{memset(h,-1,sizeof h);scanf("%d%d%d",&n,&m,&q);int siz=sqrt(n)+1;while(m--){int a,b;scanf("%d%d",&a,&b); add(a,b),add(b,a);in[a]++,in[b]++;}idx=1;for(int i=1;i<=n;i++)if(in[i]>siz)id[i]=idx++;//给大点编号1-idx-1; for(int i=1;i<=n;i++)if(id[i])//大点 for(int u=h[i];~u;u=ne[u])if(id[e[u]])//附近的大点 c[i].push_back(e[u]);for(int t=1;t<=q;t++) //大点-大点 更新大点的时候对大点无影响 { //大点-小点 更新大点的时候遍历小点int a,b; //小点-大点 更新小点的时候要把他加到对应大点的步数中因为大点对应小点的步数要枚举; scanf("%d%d",&a,&b);//小点-小点 更新小点的时候对小点没影响 bs[a]+=b; //步数加 if(id[a]&&!cham[a]) //所以如果是冠军并且是大点的话就不用了; {int ma=0; for(int i=0;i<c[a].size();i++)//大点附近的大点; {int j=c[a][i];ma=max(ma,bs[j]);if(cham[j]&&bs[a]>=bs[j])ans[j]+=t-cham[j],cham[j]=0;}for(int i=bs[a]-b+1;i<=bs[a];i++)for(auto u:B[id[a]][i])if(cham[u]&&bs[u]<=bs[a])ans[u]+=t-cham[u],cham[u]=0;//更新;
// int i=10000; //这步感觉可以存个big数组,。。。。 //不存的话就卡时间了;
// while(!B[id[a]][i].size())i--;ma=max(ma,big[a]); if(!cham[a]&&ma<bs[a])cham[a]=t;}else if(!id[a]){//小点 遍历 int ma=0;for(int i=h[a];~i;i=ne[i]){int j=e[i];ma=max(ma,bs[j]);if(id[e[i]])B[id[e[i]]][bs[a]].push_back(a),big[j]=max(big[j],bs[a]);if(cham[j]&&bs[a]>=bs[j])ans[j]+=t-cham[j],cham[j]=0;}if(bs[a]>ma&&!cham[a])cham[a]=t;}}for(int i=1;i<=n;i++){if(cham[i])ans[i]+=q-cham[i];printf(i==n?"%d":"%d\n",ans[i]);}return 0;
}