codeforces 405 C. Unusual Product and E. Graph Cutting (异或规律 & 搜索)

http://codeforces.com/problemset/problem/405/C

定义square运算:第i行向量和第i列向量的乘积的和(i从1到n)

有三种操作:

  • given a row index i, flip all the values in the i-th row in A;
  • given a column index i, flip all the values in the i-th column in A;
  • find the unusual square of A.对于第3中操作求出,square计算结果:

    分析:看一个例子,
    计算的结果是:.  flip 3 column,它计算结果是:,  其中异或之后的值,可以发现变化量是一个奇数。因为矩阵的对称性,该规律适用于所有的规模。于是,每次flip变化的影响都是对答案的一次异或。


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int m[1010][1010];
    int main()
    {
        //freopen("cin.txt","r",stdin);
        int n,q;
        while(cin>>n){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&m[i][j]);
                }
            }
            int ans=0,sum=0;
            for(int i=1;i<=n;i++){
                sum=0;
                for(int j=1;j<=n;j++){
                    sum+=m[i][j]*m[j][i];
                }
                if(sum&1) ans+=1;
            }
            if(ans&1) ans=1;
            else ans=0;
            scanf("%d",&q);
            int q1,q2,order=0;
            for(int i=0;i<q;i++){
                scanf("%d",&q1);
                if(q1==1){
                    scanf("%d",&q2);
                    order++;
                }
                if(q1==2){
                    scanf("%d",&q2);
                    order++;
                }
                if(q1==3) {
                    if(order&1){
                        ans=ans^1;
                    }
                    printf("%d",ans);
                    order=0;
                }
            }
            puts("");
        }
        return 0;
    }

    http://codeforces.com/problemset/problem/405/E

    将m条边拆成m/2条组合边(有公共点)

    感觉图论忘光了。。。(那就看别人的博客复习一下得意

    对每一个点搜索处理:

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int N=1e5+10;
    struct node{
        int u,v,next;
    }edge[N*2];
    int head[N*2],cnt;
    bool vis[N*2];
    void add(int a,int b){
        edge[cnt].u=a;
        edge[cnt].v=b;
        edge[cnt].next=head[a];
        head[a]=cnt++;
    }
    int dfs(int p1,int p2){
        queue<int> vec;
        for(int i=head[p1];i>-1;i=edge[i].next){
            int t=edge[i].v;
            if(vis[i] || t==p2) continue;
            vis[i]=vis[i^1]=1;
            int g=dfs(t,p1);
            if(g){
                printf("%d %d %d\n",p1,t,g);
            }
            else vec.push(t);
        }
        while(vec.size()>=2){
            int t1=vec.front();
            vec.pop();
            int t2=vec.front();
            vec.pop();
            printf("%d %d %d\n",t1,p1,t2);
        }
        if(vec.size()>0){
            int r=vec.front();
            vec.pop();
            return r;
        }
        return 0;
    }
    int main()
    {
        //freopen("cin.txt","r",stdin);
        int n,m;
        while(cin>>n>>m){
            memset(head,-1,sizeof(head));
            memset(vis,0,sizeof(vis));
            cnt=0;
            int a,b;
            for(int i=0;i<m;i++){
                scanf("%d%d",&a,&b);
                add(a,b);
                add(b,a);
            }
            if(m&1){
                puts("No solution");
                continue;
            }
            dfs(1,-1);
        }
        return 0;
    }
    


  • 你可能感兴趣的:(codeforces)