本题两种思路:
第一种是直接暴力模拟,每次都更新点,查询时算sum。
代码:
#include
#include
#include
#include
#include
#define N 100005
using namespace std;
int a[N];
vector V[N];
int main(){
int t, n, m, u, v;
cin>>t;
while(t--){
scanf("%d%d", &n, &m);
memset(a, 0, sizeof(a));
for(int i = 0; i <= n; i++)
V[i].clear();
for(int i = 0; i < m; i++){
scanf("%d%d", &u, &v);
V[u].push_back(v);
V[v].push_back(u);
}
int q, cmd;
scanf("%d", &q);
while(q--){
scanf("%d", &cmd);
if(cmd == 0){
scanf("%d%d", &u, &v);
a[u] += v;
}
else{
scanf("%d", &u);
long long sum = 0;
for(int i = 0; i < V[u].size();i++)
sum += a[V[u][i]];
printf("%lld\n", sum);
}
}
}
return 0;
}
方法是:使用分块的方法。
一共有m条边,因此点的度数之和为2m,将度数>=sqrt(m)的点记为重点,
将此题做以下处理:
建图(使用邻接表):
如果该点是轻点,直接加入这条边;(轻点的边数小于sqrt(m))
如果该点是重点,只添加另一个点是重点的边;(重点数小于sqrt(2m)个,因此边数也少于sqrt(2m)个)
更新:
先更新自己的val值,再遍历相邻点:
如果相邻点是重点,则更新相邻点的sum值。
查询:
如果该点是重点,直接输出该点的sum值;
如果该点是轻点,则遍历相邻点,求它们的val之和。
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
#define N 100005
vector V[N];
struct node{
long long val, sum;
}Node[N];
struct edge{
int u, v;
}Edge[N+10];
int cnt[N];
int S;
void update(int u, int v){
Node[u].val += v;
for(int i = 0; i < V[u].size(); i++){
if(cnt[V[u][i]] >= S)//重边
Node[V[u][i]].sum += v;
}
}
void query(int u){
if(cnt[u] >= S)
printf("%lld\n", Node[u].sum);
else{
long long sum = 0;
for(int i = 0; i < V[u].size(); i++){
sum += Node[V[u][i]].val;
}
printf("%lld\n", sum);
}
}
int main(){
int t, m, n, u, v;
cin>>t;
while(t--){
cin>>n>>m;
S = sqrt(m);
for(int i = 1; i <= n; i++){
V[i].clear();
Node[i].val = Node[i].sum = 0;
cnt[i] = 0;
}
for(int i = 0; i < m; i ++){//input edge
scanf("%d%d", &u, &v);
Edge[i].u = u;
Edge[i].v = v;
cnt[u]++;
cnt[v]++;
}
for(int i = 0; i < m; i ++){//build graph
u = Edge[i].u, v = Edge[i].v;
if(cnt[u] < S) V[u].push_back(v);
else if(cnt[v] >= S)V[u].push_back(v);
if(cnt[v] < S) V[v].push_back(u);
else if(cnt[u] >= S)V[v].push_back(u);
}
int q, cmd;
scanf("%d", &q);
while(q--){
scanf("%d", &cmd);
if(cmd == 0){
scanf("%d%d", &u, &v);
update(u, v);
}else{
scanf("%d", &u);
query(u);
}
}
}
return 0;
}