zoukankan      html  css  js  c++  java
  • HAOI2018 反色游戏

    传送门

    这个题一开始他们说什么列异或方程组我也不懂……根据学姐告诉我的结论,如果联通块内有一棵树的话,那么其他的非树边反转或者不反转都行,反正树是能给你还原回去的。不过如果有奇数个黑点是不行的。
    根据这个结论,记录联通块个数为tot,那么不删点的时候答案就是(2^{m-n+tot})
    然后对于删点……和yyb大神学的……如果这个点是割点,那么首先我们看它所连接的联通块中有没有有奇数个黑点的,如果有就不行。
    之后再看它上面的联通块中是否有奇数个黑点,有就不行。
    如果这个联通块外也有奇数个黑点……还是不行……
    否则的话答案就是在原来的基础上,减去点度,加上1,再加上获得的新联通块个数,原理和上面是一样的。
    注意如果是根的话获得的新联通块个数要-1,因为上面没了。

    #include<bits/stdc++.h>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    const int mod = 1e9+7;
    
    int read()
    {
       int ans = 0,op = 1;char ch = getchar();
       while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
       while(ch >='0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
       return ans * op;
    }
    
    struct edge
    {
       int next,to,from;
    }e[M<<1];
    
    int n,m,head[M],ecnt,dfn[M],low[M],vis[M],idx,root,T;
    int sum[M],c[M],d[M],f[M],deg[M],po[M<<1],a[M],val,tot,x,y;
    char s[M];
    void add(int x,int y){e[++ecnt] = {head[x],y,x},head[x] = ecnt,deg[y]++;}
    void clear()
    {
       ecnt = idx = val = tot = 0;
       rep(i,1,n) head[i] = dfn[i] = low[i] = deg[i] = d[i] = c[i] = f[i] = 0;
    }
    
    void tarjan(int x)
    {
       dfn[x] = low[x] = ++idx,vis[x] = root,sum[x] = a[x];
       for(int i = head[x];i;i = e[i].next)
       {
          int t = e[i].to;
          if(!dfn[t])
          {
    	 tarjan(t),sum[x] += sum[t];
    	 low[x] = min(low[x],low[t]);
    	 if(low[t] >= dfn[x]) d[x] |= (sum[t] & 1),c[x]++,f[x] += sum[t];
          }
          else low[x] = min(low[x],dfn[t]);
       }
       if(x == root) c[x]--;
    }
    
    int main()
    {
       po[0] = 1;
       rep(i,1,(M<<1)-1) po[i] = (po[i-1] << 1) % mod;
       T = read();
       while(T--)
       {
          n = read(),m = read(),clear();
          rep(i,1,m) x = read(),y = read(),add(x,y),add(y,x);
          scanf("%s",s+1);
          rep(i,1,n) a[i] = s[i] - '0';
          rep(i,1,n) if(!dfn[i]) root = i,tarjan(i),tot++,val += sum[i] & 1;
          val ? printf("0 ") : printf("%d ",po[m-n+tot]);
          rep(i,1,n)
          {
    	 if(d[i]) printf("0 ");
    	 else if(val - (sum[vis[i]] & 1)) printf("0 ");
    	 else if((sum[vis[i]] - a[i] - f[i]) & 1) printf("0 ");
    	 else printf("%d ",po[m-n+tot-deg[i]+1+c[i]]);
          }
          enter;
       }
       return 0;
    }
    
    
  • 相关阅读:
    UI
    最长回文子串
    LRU缓存机制
    环形链表 II
    环形链表
    买卖股票的最佳时机 II
    [CSP-S模拟测试]:连连看(图论+容斥)
    [CSP-S模拟测试]:集合论(模拟)
    [CSP-S模拟测试]:位运算(数学)
    [CERC2016]:凸轮廓线Convex Contour(模拟+数学)
  • 原文地址:https://www.cnblogs.com/captain1/p/10603888.html
Copyright © 2011-2022 走看看