这题采不采用分治法都是可以的,采用分治法就是效率高些,以空间换取时间。
直接暴力:
#include<iostream> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #define maxn 100100 using namespace std; vector<int>mapp[maxn]; long long num[maxn]; long long sum=0; int main() { int T,i,j,n,m,u,v,Q,a,b,c; scanf("%d",&T); while(T--) { scanf("%d %d",&n,&m); for(i=1;i<=n;i++) mapp[i].clear(); //memset(sum,0,sizeof(sum)); memset(num,0,sizeof(num)); for(i=1;i<=m;i++) { scanf("%d %d",&u,&v); mapp[u].push_back(v); mapp[v].push_back(u); } scanf("%d",&Q); for(j=1;j<=Q;j++) { scanf("%d",&a); if(a==0) { scanf("%d %d",&b,&c); num[b]+=c; } else { scanf("%d",&b); for(i=0;i<mapp[b].size();i++) { sum+=num[mapp[b][i]]; } cout<<sum<<endl; sum=0; } } } return 0; }
#include<iostream> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #define maxn 100100 using namespace std; vector<int>mapp[maxn]; vector<int>heavy[maxn]; int sum[maxn]; int du[maxn]; int num[maxn]; int T,i,j,n,m,u,v,a,b,c,Q; void Scan() { scanf("%d%d",&n,&m); memset(du,0,sizeof(du)); for(i=1;i<=n;i++) { mapp[i].clear(); heavy[i].clear(); } for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); mapp[u].push_back(v); mapp[v].push_back(u); du[u]++; du[v]++; } for(i=1;i<=n;i++) { for(j=0;j<mapp[i].size();j++) { int k=mapp[i][j]; if(du[k]>sqrt(n)) { heavy[i].push_back(k); } } } } void Question() { memset(num,0,sizeof(num)); memset(sum,0,sizeof(sum)); scanf("%d",&Q); for(i=1;i<=Q;i++) { scanf("%d",&a); if(a==0) { scanf("%d%d",&b,&c); num[b]+=c; for(j=0;j<heavy[b].size();j++) { sum[heavy[b][j]]+=c; } } else { scanf("%d",&b); if(du[b]>sqrt(n))printf("%d\n",sum[b]); else { int all=0; for(j=0;j<mapp[b].size();j++) { all+=num[mapp[b][j]]; } cout<<all<<endl; } } } } int main() { scanf("%d",&T); while(T--) { Scan(); Question(); } return 0; }