zoukankan      html  css  js  c++  java
  • HDOJ 4858 项目管理 ( 只是有点 莫队的分块思想在里面而已啦 )

    题目: 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858

                题意:

              我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!
              两个节点间可能有多条边,不过一条边的两端必然是不同的节点。
              每个节点都有一个能量值。
    
              现在我们要编写一个项目管理软件,这个软件呢有两个操作:
              1.给某个项目的能量值加上一个特定值。
              2.询问跟一个项目相邻的项目的能量值之和。(如果有多条边就算多次,比如a和b有2条边,那么询问a的时候b的权值算2次)。

    思路: 分成 重点 和 轻点 重点就是度数大于一个你自己设定的值的点( 我设为 sqrt(m)) ,其他点为起点,度数就是和你存在边的点,因为题目允许两个点有两条边,所以一个点对和它相连的点 的度数 的贡献 可能大于1
    然后自己建图的时候,重点只和重点连边,轻点和所有点连 ( 因为和重点相连的点就是比较多的,你每次对重点 的能量值的修改都去枚举和它相连的点的话咧,就时间复杂度很高嘛,所以就索性不全部枚举了,只枚举和它相连的点的集合中同样是重点的点 ,记录贡献 ,然后那些没被枚举到的点都是轻点 )
    (这样子就是 修改某个点的能量值 受影响的重点都会被枚举到,且修改权值,但是 对于轻点来说 是不一定被枚举到的,所以询问轻点就不能直接输出 sum [ x] ,只有重点可以)
    然后咧,对于重点的询问,直接输出 sum [ x ], 对于轻点的询问就暴力 枚举 和它相连的点的集合 的 能量值 加起来就是答案了


    其实就是分摊复杂度嘛,重点暴力枚举的话就复杂度很高,所以就采用分块的思想。

    #include<bits/stdc++.h>
    #define LL long long
    #define ULL unsigned long long
    #define rep(i,j,k) for(int i=j;i<=k;i++)
    #define dep(i,j,k) for(int i=k;i>=j;i--)
    #define INF 0x3f3f3f3f
    #define mem(i,j) memset(i,j,sizeof(i))
    #define make(i,j) make_pair(i,j)
    #define pb push_back
    using namespace std;
    const int N=1e5+100;
    vector<LL>G[N];
    struct note {
        LL st,en;
    }a[N];
    LL du[N];
    LL ans[N],sum[N];
    bool vis[N];
    int main() {
        LL t; LL n,m;
        scanf("%lld",&t);
        while(t--) {
            scanf("%lld %lld",&n,&m);
            rep(i,1,n) { du[i]=ans[i]=sum[i]=0;G[i].clear();vis[i]=false; }
            LL block=sqrt(m);
            rep(i,1,m) {
                 scanf("%lld %lld",&a[i].st,&a[i].en);
                 if(++du[a[i].st]>block ) vis[a[i].st]=true;
                 if(++du[a[i].en]>block) vis[a[i].en]=true;
            }
            rep(i,1,m) {
                LL x=a[i].st,y=a[i].en;
                if(vis[x]) {
                    if(vis[y]) {
                        G[x].pb(y);
                        G[y].pb(x);
                    }
                    else G[y].pb(x);
                }
                else {
                    if(vis[y]) G[x].pb(y);
                    else {
                        G[x].pb(y);
                        G[y].pb(x);
                    }
                }
            }
            LL q;
            scanf("%lld",&q); LL op;
            LL x; LL y;
            while(q--) {
                scanf("%lld",&op);
                if(op==0) {
                    scanf("%lld %lld",&x,&y);
                    sum[x]+=y;
                    rep(i,0,(LL)G[x].size()-1) {
                        //puts("1");
                        LL v=G[x][i]; ans[v]+=y;
                    }
                    //puts("1");
                }
                else {
                    scanf("%lld",&x);
                    if(vis[x]) printf("%lld
    ",ans[x]);
                    else {
                        LL tmp=0;
                        rep(i,0,(LL)G[x].size()-1) {
                            int v=G[x][i]; tmp+=sum[v];
                        }
                        printf("%lld
    ",tmp);
                    }
                }
            }
        }
        return 0;
    }
    View Code
    一步一步,永不停息
  • 相关阅读:
    Word批量转PDF(内容转图片,防复制文字)
    Word批量转PDF或者图片(实现方式二)
    Word批量生成软件(实现方式三)
    合同批量生成软件/工具(实现方式三)
    Word批量打印软件/工具
    Word文件批量查找替换字符串
    Word批量生成软件(实现方式二)
    Word批量生成软件
    合同批量生成软件/工具(实现方式二)
    MySQL处理大量数据的效率问题
  • 原文地址:https://www.cnblogs.com/Willems/p/10896846.html
Copyright © 2011-2022 走看看