zoukankan      html  css  js  c++  java
  • HDOJ4467 ( 分块 思想 )

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

               题意:给你n个点(每个点都有一个颜色,0代表黑色,1代表白色),m条边,每条边有一个权值.现在有有两个操作,一个是修改某个点的颜色(白变成黑/黑变成白),另外一个是询问那些边的两个端点                        都为指定颜色的权值总和

    思路:将所有点分为重点和轻点,但是这次重点和重点之前的边要建在一个图中,剩余的边要建在另一个图中。对于最后访问的颜色,只有三种情况黑+黑(求和为0),黑+白(求和为1),白+白(求和为                     2),所以用ans[0],ans[1],ans[2]分别对应的答案。对于重点i设置一个sum[i][2],sum[i][0]表示所有与他相邻且颜色为0(黑)的点的边权之和,sum[i][1]同理。更新时,对于重点i来说拿sum[i][0]和sum[i][1]            去直接更新a数组,同时将其相邻的重点的sum值进行修改。而对于轻点i来说,遍历所有与i相连的边,暴力更新a数组,而当其相邻点为重点时则需要更新一下重点的sum数组。对于查询操作,直接输出                ans数组 中的  值即可  (转自 : https://www.cnblogs.com/HDUjackyan/p/8996172.html)

    #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+10;
    int c[N],du[N];
    LL ans[5],sum[N][5];
    bool vis[N];
    struct note {
        int u,v;
        LL w;
    }a[N];
    vector< pair<int,LL> > Z[N],Q[N];
    bool cmp (note a,note b) {
        return a.u==b.u?a.v<b.v:a.u<b.u;
    }
    char op[10];
    int main() {
        int n,m; int cas=0;
        while(~scanf("%d %d",&n,&m)) {
            rep(i,1,n) scanf("%d",&c[i]);
            rep(i,1,n) {
                du[i]=0; vis[i]=false; sum[i][0]=sum[i][1]=0;
                Z[i].clear(); Q[i].clear();
            }
            mem(ans,0);
            rep(i,1,m) {
                scanf("%d %d %lld",&a[i].u,&a[i].v,&a[i].w);
                if(a[i].u>a[i].v) swap(a[i].u,a[i].v);
                ans[c[a[i].u]+c[a[i].v]]+=a[i].w;
            }
            sort(a+1,a+1+m,cmp);
            int I,J; int head=0;
            for(I=1;I<=m;I=J) {
                for(J=I+1;J<=m;J++) {
                    if(a[I].u==a[J].u && a[I].v==a[J].v) {
                        a[I].w+=a[J].w;
                    }
                    else break;
                }
                a[++head]=a[I];
            }
            int block=sqrt(head);
            rep(i,1,head) {
                if(++du[a[i].u]>block) vis[a[i].u]=true;
                if(++du[a[i].v]>block) vis[a[i].v]=true;
            }
            int x,y; LL z;
            rep(i,1,head) {
                x=a[i].u; y=a[i].v; z=a[i].w;
                if(vis[x]) {
                    if(vis[y]) {
                        Z[x].pb(make(y,z));
                        Z[y].pb(make(x,z));
                        sum[x][c[y]]+=z;
                        sum[y][c[x]]+=z;
                    }
                    else {
                        Q[y].pb(make(x,z));
                        sum[x][c[y]]+=z;
                    }
                }
                else {
                    if(vis[y]) {
                        Q[x].pb(make(y,z));
                        sum[y][c[x]]+=z;
                    }
                    else {
                        Q[x].pb(make(y,z));
                        Q[y].pb(make(x,z));
                    }
                }
            }
            int q;
            printf("Case %d:
    ",++cas);
            scanf("%d",&q);
            while(q--) {
                scanf("%s",op);
                if(op[0]=='A') {
                    scanf("%d %d",&x,&y);
                    printf("%lld
    ",ans[x+y]);
                }
                else {
                    scanf("%d",&x);
                    if(vis[x]) {
                        ans[c[x]+0]-=sum[x][0];
                        ans[c[x]+1]-=sum[x][1];
                        ans[1-c[x]+0]+=sum[x][0];
                        ans[1-c[x]+1]+=sum[x][1];
                        int len=Z[x].size()-1;
                        rep(i,0,len) {
                            y=Z[x][i].first; z=Z[x][i].second;
                            sum[y][c[x]]-=z;
                            sum[y][1-c[x]]+=z;
                        }
                    }
                    else {
                        int len=Q[x].size()-1;
                        rep(i,0,len) {
                            y=Q[x][i].first; z=Q[x][i].second;
                            ans[c[x]+c[y]]-=z;
                            ans[1-c[x]+c[y]]+=z;
                            if(vis[y]) {
                                sum[y][c[x]]-=z;
                                sum[y][1-c[x]]+=z;
                            }
                        }
                    }
                    c[x]=1-c[x];
                }
            }
        }
        return 0;
    }
    View Code
    一步一步,永不停息
  • 相关阅读:
    PMM Client 安装异常报错
    安装Docker时错误提示 "could not change group /var/run/docker.sock to docker: group docker not found"的解决方案
    简单概括下MongoDB 4.0 新特性
    MySQL 关于性能的参数配置梳理
    MySQL数据库在IO性能优化方面的设置选择(硬件)
    MongoDB 集合间关联查询后通过$filter进行筛选
    MySQL 基础知识梳理学习(七)----sync_binlog
    第八章 (一)分治 练习题
    第八章 (一)分治
    Logistic回归
  • 原文地址:https://www.cnblogs.com/Willems/p/10902104.html
Copyright © 2011-2022 走看看