题意:给n(<=100000)个点,m条边( <=n+10),可能有重边,每个点有个值val,初识为0。
2种操作。
操作1:点x的值,加addx。
操作2:输出x点的邻点的val和。
分析:简单的优化操作1或操作2是不行的。
法一:针对点的度将图中点分为两类点。对于度大于sqrt (n)的点为重点,对于小于等于sqrt(n)的点为轻点。 重点的个数小于sqrt(n)个。针对重点和轻点分别处理。
法二:也可考虑每个点,将其邻点分类。大于该点度的点分为一类,等于该点的度的分为一类,小于该点的度的点分为一类。分别处理。
法一:
const int maxn = 100100;
vector<int>v[maxn], vgt[maxn];
int d[maxn];
int val[maxn];
int sum[maxn];
int n, m;
const int MM = 3333;
int main ()
{
int T;
cin >> T;
while (T--)
{
scanf("%d%d", &n, &m);
memset(d, 0, sizeof(d));
memset(val, 0, sizeof(val));
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; i++)
{
v[i].clear(); vgt[i].clear();
}
for (int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y); v[y].push_back(x);
d[x]++; d[y]++;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < v[i].size(); j++)
{
int r = v[i][j];
if (d[r] > MM) vgt[i].push_back(r);
}
}
int Q;
cin >> Q;
while (Q--)
{
int op;
int x, addx;
scanf("%d", &op);
if (!op)
{
scanf("%d%d", &x, &addx);
val[x] += addx;
if (d[x] <= MM)
{
for (int i = 0; i < vgt[x].size(); i++)
{
int y = vgt[x][i];
sum[y] += addx;
}
}
}
else
{
scanf("%d", &x);
int ans = 0;
if (d[x] <= MM)
{
for (int i = 0; i < v[x].size(); i++)
{
ans += val[v[x][i]];
}
}
else
{
ans += sum[x];
for (int i = 0; i < vgt[x].size(); i++)
{
int y = vgt[x][i];
ans += val[y];
}
}
printf("%d\n", ans);
}
}
}
return 0;
}
/**
4
3 2
1 2
1 3
6
0 1 15
0 3 4
1 1
1 3
0 2 33
1 2
3 2
1 2
1 2
6
0 1 15
1 1
0 2 15
1 1
1 3
*/
const int maxn = 100100;
vector<int>v[maxn], vgt[maxn], veq[maxn];
int d[maxn];
int val[maxn];
int sum[maxn];
int n, m;
const int MM = 3333;
int main ()
{
int T;
cin >> T;
while (T--)
{
scanf("%d%d", &n, &m);
memset(d, 0, sizeof(d));
memset(val, 0, sizeof(val));
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; i++)
{
v[i].clear(); vgt[i].clear(); veq[i].clear();
}
for (int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
v[x].push_back(y); v[y].push_back(x);
d[x]++; d[y]++;
}
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < v[i].size(); j++)
{
int r = v[i][j];
if (d[r] > d[i]) vgt[i].push_back(r);
else if (d[r] == d[i]) veq[i].push_back(r);
}
}
int Q;
cin >> Q;
while (Q--)
{
int op;
int x, addx;
scanf("%d", &op);
if (!op)
{
scanf("%d%d", &x, &addx);
val[x] += addx;
for (int i = 0; i < vgt[x].size(); i++)
sum[vgt[x][i]] += addx;
}
else
{
scanf("%d", &x);
int ans = sum[x];
for (int i = 0; i < vgt[x].size(); i++)
ans += val[vgt[x][i]];
for (int i = 0; i < veq[x].size(); i++)
ans += val[veq[x][i]];
printf("%d\n", ans);
}
}
}
return 0;
}
/**
4
3 2
1 2
1 3
6
0 1 15
0 3 4
1 1
1 3
0 2 33
1 2
3 2
1 2
1 2
6
0 1 15
1 1
0 2 15
1 1
1 3
*/