Graph HDU - 4467

https://vjudge.net/problem/HDU-4467

大概就是,设一个块大小T

对于度数<=T的点,设为1类点,在改变颜色的时候暴力查询与其相邻点,更新答案

对于度数>T的点,设为2类点,分别维护与其相邻的颜色为0/1的点之间的边权和(记录与每个点相连的所有2类点,然后在任意点(注意2类点也要)改变颜色时维护一下与其相连2类点的这个值),改变颜色的时候根据维护的值O(1)可以计算出对答案的修改

说的再简单一点,1类点由自身去更新其他,2类点由其他去更新自身。。复杂度很容易发现是根号级别的(T=sqrt(m))

但是要注意,重边一定要去。。。不然可以被卡到$n^2$

错误记录:

1.没有在改变2类点颜色时改变相连其他2类点维护的值

2.没有去重边

3.d[a],d[b]和a,b没有极其仔细地区分

  1 //#pragma GCC optimize(3)
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<vector>
  6 #include<set>
  7 #include<map>
  8 using namespace std;
  9 #define fi first
 10 #define se second
 11 #define mp make_pair
 12 #define pb push_back
 13 typedef long long ll;
 14 typedef unsigned long long ull;
 15 typedef pair<int,int> pii;
 16 #define N 100000
 17 struct E
 18 {
 19     int to,nxt;ll d;
 20 }e[2*N+100];
 21 int f1[N+100],ne;
 22 int TT,n,m,mm,d[N+100];
 23 int in[N+100],sz,q;
 24 //1类点:in[i]<=sz;2类点:in[i]>sz
 25 ll a1[N+100][2];
 26 //a1[i][j]:i为2类点,i与相邻的颜色为j的点之间的所有边的权值和
 27 //int num[100100];
 28 char tmp[10];
 29 vector<int> ss[N+100];//ss[i]:i点到相邻的2类点的边
 30 ll ans[3];//ans[0]:00边答案;ans[1]:11边答案;ans[2]:01边答案
 31 map<pii,pii> ma;
 32 ll &gg(int a,int b)
 33 {
 34     if(a==0&&b==0)    return ans[0];
 35     if(a==1&&b==1)    return ans[1];
 36     return ans[2];
 37 }
 38 int main()
 39 {
 40     int a,b,c,i,k;pii t;
 41     while(scanf("%d%d",&n,&m)==2)
 42     {
 43         TT++;mm=0;//num[0]=0;
 44         memset(f1,0,sizeof(f1));ne=0;ma.clear();
 45         memset(in,0,sizeof(in));ans[0]=ans[1]=ans[2]=0;
 46         memset(a1,0,sizeof(a1));
 47         for(i=1;i<=n;i++)    scanf("%d",&d[i]);
 48         for(i=1;i<=m;i++)
 49         {
 50             scanf("%d%d%d",&a,&b,&c);
 51             if(a>b)    swap(a,b);
 52             if(ma.count(mp(a,b)))
 53             {
 54                 t=ma[mp(a,b)];
 55                 e[t.fi].d+=c;e[t.se].d+=c;
 56             }
 57             else
 58             {
 59                 e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;e[ne].d=c;
 60                 e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;e[ne].d=c;
 61                 in[a]++;in[b]++;
 62                 ma[mp(a,b)]=mp(ne-1,ne);mm++;
 63             }
 64             gg(d[a],d[b])+=c;
 65         }
 66         sz=sqrt(2*mm);
 67         for(i=1;i<=n;i++)
 68             if(in[i]>sz)
 69             {
 70                 //num[++num[0]]=i;
 71                 for(k=f1[i];k;k=e[k].nxt)
 72                     a1[i][d[e[k].to]]+=e[k].d;
 73             }
 74         for(i=1;i<=n;i++)
 75         {
 76             ss[i].clear();
 77             for(k=f1[i];k;k=e[k].nxt)
 78                 if(in[e[k].to]>sz)
 79                     ss[i].pb(k);
 80         }
 81         scanf("%d",&q);
 82         printf("Case %d:\n",TT);
 83         while(q--)
 84         {
 85             scanf("%s",tmp);
 86             if(tmp[0]=='A')
 87             {
 88                 scanf("%d%d",&a,&b);
 89                 printf("%lld\n",gg(a,b));
 90             }
 91             else
 92             {
 93                 scanf("%d",&a);
 94                 if(in[a]<=sz)
 95                 {
 96                     for(k=f1[a];k;k=e[k].nxt)
 97                     {
 98                         b=e[k].to;
 99                         gg(d[a],d[b])-=e[k].d;
100                         if(in[b]>sz)    a1[b][d[a]]-=e[k].d;
101                     }
102                     d[a]^=1;
103                     for(k=f1[a];k;k=e[k].nxt)
104                     {
105                         b=e[k].to;
106                         gg(d[a],d[b])+=e[k].d;
107                         if(in[b]>sz)    a1[b][d[a]]+=e[k].d;
108                     }
109                 }
110                 else
111                 {
112                     for(i=0;i<ss[a].size();i++)
113                         a1[e[ss[a][i]].to][d[a]]-=e[ss[a][i]].d;
114                     gg(d[a],0)-=a1[a][0];gg(d[a],1)-=a1[a][1];
115                     d[a]^=1;
116                     gg(d[a],0)+=a1[a][0];gg(d[a],1)+=a1[a][1];
117                     for(i=0;i<ss[a].size();i++)
118                         a1[e[ss[a][i]].to][d[a]]+=e[ss[a][i]].d;
119                 }
120             }
121         }
122     }
123     return 0;
124 }

 

posted @ 2018-07-18 08:31  hehe_54321  阅读(173)  评论(0编辑  收藏  举报
AmazingCounters.com