HDU 4858 项目管理(点分块)

来源:互联网 发布:网络运营总监培训 编辑:程序博客网 时间:2024/06/16 12:38

题意:给出一张图,两种操作
1.将点x加上权值y
2.询问与点x相邻点的权值和

分析:将点分为重点和轻点,度数大于等于sqrtm为重点,小于的为轻点,将重点和相邻重点连边,轻边和相邻所有边连边,得到规律,重点的答案是由周围重点和轻点对它的加成组成,而轻点答案直接由相邻点组成,复杂度 Oqsqrtm

#include<cstring>#include<string>#include<iostream>#include<queue>#include<cstdio>#include<algorithm>#include<map>#include<cstdlib>#include<cmath>#include<vector>//#pragma comment(linker, "/STACK:1024000000,1024000000");using namespace std;#define INF 0x3f3f3f3f#define maxn 200004int n,m;int x[maxn],y[maxn];int fir[maxn],nex[maxn],v[maxn],e_max;int in[maxn];int sum[maxn],val[maxn];bool heavy[maxn];void init(){    memset(sum,0,sizeof sum);    memset(val,0,sizeof val);    memset(heavy,false,sizeof heavy);    memset(in,0,sizeof in);    memset(fir,-1,sizeof fir);    e_max=0;}void add_edge(int s,int t){    int e=e_max++;    v[e]=t;    nex[e]=fir[s];    fir[s]=e;}void build(){    int block=sqrt(m);    for(int i=1; i<=n; i++)    {        if(in[i]>=block) heavy[i]=true;    }    for(int i=0; i<m; i++)    {        int u=x[i],v=y[i];        if(heavy[u]&&heavy[v])        {            add_edge(u,v);            add_edge(v,u);        }        if(!heavy[u]) add_edge(u,v);        if(!heavy[v]) add_edge(v,u);    }}void update(int x,int y){    val[x]+=y;    if(!heavy[x])    {        for(int i=fir[x]; ~i; i=nex[i])        {            int e=v[i];            sum[e]+=y;        }    }}int query(int x){    int ans=0;    if(heavy[x]) ans+=sum[x];    for(int i=fir[x]; ~i; i=nex[i])    {        int e=v[i];        ans+=val[e];    }    return ans;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        init();        scanf("%d%d",&n,&m);        for(int i=0; i<m; i++)        {            scanf("%d%d",&x[i],&y[i]);            in[x[i]]++;            in[y[i]]++;        }        build();        int q;        scanf("%d",&q);        while(q--)        {            int op;            scanf("%d",&op);            if(!op)            {                int x,y;                scanf("%d%d",&x,&y);                update(x,y);            }            else            {                int x;                scanf("%d",&x);                printf("%d\n",query(x));            }        }    }    return 0;}
0 0
原创粉丝点击