n , m , Q ≤ 3 × 1 0 5 , y ≤ 1000 n,m,Q \leq 3 \times 10^5 , y \leq 1000 n,m,Q≤3×105,y≤1000
考试时一开始想的是怎么搞,先想了线段树,后来发现不行,看数据范围 O ( n n ) O(n\sqrt{n}) O(nn)能过,于是想了莫队发现不好做,突然想起昨天提到了的根号分治,发现好像可行,于是想了一波。
由于度数大于 2 m \sqrt{2m} 2m的点不超过 2 m \sqrt{2m} 2m个。分开考虑。对每个点记录一个 a n s [ i ] ans[i] ans[i]和 v a l [ i ] val[i] val[i]
考虑修改:
修改一次最多为 O ( 2 m ) O(\sqrt{2m}) O(2m)。
考虑查询:
对于第一种情况,查询一次最多为 O ( 2 m ) O(\sqrt{2m}) O(2m)
对于第二种情况,查询一次为 O ( 1 ) O(1) O(1)
/*******************************
Author:galaxy yr
LANG:C++
Created Time:2019年10月23日 星期三 08时44分36秒
*******************************/
#include
#include
#include
#include
#include
using namespace std;
struct IO{
template<typename T>
IO & operator>>(T&res)
{
T q=1;char ch;
while((ch=getchar())<'0' or ch>'9')if(ch=='-')q=-q;
res=(ch^48);
while((ch=getchar())>='0' and ch<='9') res=(res<<1)+(res<<3)+(ch^48);
res*=q;
return *this;
}
}cin;
struct edge{
int to,next;
edge(int a=0,int b=0):to(a),next(b){}
};
struct Node{
int u,v;
Node(int a=0,int b=0):u(a),v(b){}
bool operator<(const Node & p) const
{
if(u==p.u) return v<p.v;
return u<p.u;
}
};
const int maxn=3e5+10;
int n,m,q,du[maxn],head[maxn],cnt,LIM,ct,hd[maxn],a[maxn],b[maxn];
long long ans[maxn],val[maxn];
bool big[maxn];
vector<int>V[maxn],G[maxn];
set<Node>S;
inline void query_big(const int & x)
{
printf("%lld\n",ans[x]);
}
inline void query_small(const int & x)
{
long long res=ans[x];
for(int i=0;i<V[x].size();i++)
res+=val[V[x][i]];
printf("%lld\n",res);
}
inline void modify(const int & x,const int & y)
{
val[x]+=y,ans[x]+=y;
for(int i=0;i<G[x].size();i++)
ans[G[x][i]]+=y;
}
int main()
{
//freopen("sibyl.in","r",stdin);
//freopen("sibyl.out","w",stdout);
cin>>n>>m>>q; LIM=300;
int u,v;
for(int i=1;i<=m;i++)
{
cin>>u>>v;
a[i]=u,b[i]=v;
if(u==v) continue;
if(u>v) swap(u,v);
if(S.count(Node(u,v))) continue;
S.insert(Node(u,v));
du[u]++,du[v]++;
V[u].push_back(v);
V[v].push_back(u);
}
for(int i=1;i<=n;i++)
if(du[i]>=LIM)
big[i]=1;
for(int i=1;i<=m;i++)
{
if(big[a[i]])
G[b[i]].push_back(a[i]);
if(big[b[i]])
G[a[i]].push_back(b[i]);
}
int opt,x,y;
while(q--)
{
cin>>opt>>x;
if(opt==0)
{
if(big[x])
query_big(x);
else
query_small(x);
}
else
{
cin>>y;
modify(x,y);
}
}
return 0;
}