• 湖南省第十一届大学生程序设计竞赛:Internet of Lights and Switches(HASH+二分+异或前缀和)


    Internet of Lights and Switches

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 3  Solved: 3
    [Submit][Status][Web Board]

    Description

    You are a fan of "Internet of Things"(IoT, 物联网), so you build a nice Internet of Lights and Switches in your huge mansion. Formally, there are n lights and m switches, each switch controls one or more lights, i.e. pressing that switch flips the status of those lights (on->off, off->on).   Initially, all the lights are on. Your task is to count the number of ways to turn off all the lights by pressing some consecutive switches. Each switch should not be pressed more than once. There is only one restriction: the number of switches you pressed should be between a and b (inclusive).  

    Input

    There will be at most 20 test cases. Each test case begins with a line containing four integers n, m, a, b(2<=n<=50, 1<=a<=b<=m<=300000). Each of the following m lines contains a 01 string of length n.The i-th character is 1 if and only if that switch controls the i-th light. The size of the whole input file
    does not exceed 8MB.  

    Output

    For each test case, print the case number, and the number of ways to turn off all the lights.  

    Sample Input

    2 4 1 4
    01
    10
    11
    00
    2 4 3 3
    01
    10
    11
    00
    6 3 1 3
    101001
    010110
    101001

    Sample Output

    Case 1: 3
    Case 2: 0
    Case 3: 2


    题意:现在有m盏灯,有n个开关(m<=50,n<=300000) 现在开关用01串表示,为1表示开关可以操作当前的灯,现在必须操纵连续k盏灯使得这些这些灯全部关闭,A<=k<=B,问现在有多少这样连续的开关满足条件?
    题解:去年省赛竟然有几支队A了,ORZ,映射好难想到啊~.这题的话我们保存一个异或前缀和,如果某段的异或和为全1,那么这段就是可取的.但是怎么找到呢?我们假设xorsum[1,i]^xorsum[1,j] 为全1.那么xor[j+1,i]是符合条件的,关键是怎么找到这个区间?这时候就要用到hash了,用map映射满足当前异或前缀和的所有下标。用一个vector记录,然后输入的时候,只要查询 i 前面有多少个下标的异或值为 1111111...^xor[1,x], 然后可以二分查询当前的下标距离 i 必须为 A~B 之间,在这个范围内满足的下标的个数就是当前与 i 组合成为区间满足条件的个数,还有一种情况就是[1,i]这个区间满足条件,这种情况直接++即可.
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include <algorithm>
    #include <map>
    #include <vector>
    using namespace std;
    typedef long long LL;
    char str[80];
    const int INF = 999999999;
    map<LL,vector<int> > mp;
    int n,m,A,B;
    LL charToLL(char *str){
        LL ans = 0;
        int p = 1,len = strlen(str);
        for(int i=len-1;i>=0;i--){
            if(str[i]=='1'){
                ans+=p;
            }
            p*=2;
        }
        return ans;
    }
    int binary(LL val,int id){
        vector <int> vec = mp[val];
        int down = 0,up = vec.size()-1,r=-1,l=INF;
        while(down<=up){
            int mid = (down+up)>>1;
            if(id-vec[mid]>=A){
                r = mid;
                down = mid+1;
            }else up = mid-1;
        }
        down = 0,up = vec.size()-1;
        while(down<=up){
            int mid = (down+up)>>1;
            if(id-vec[mid]<=B){
                l = mid;
                up = mid-1;
            }else down = mid+1;
        }
        //printf("%d %d
    ",l,r);
        if(l>r) return 0;
        return r-l+1;
    }
    int main(){
        int t = 1;
        while(scanf("%d%d%d%d",&m,&n,&A,&B)!=EOF){
            mp.clear();
            for(int i=0;i<m;i++){
                str[i] = '1';
            }
            str[m]='';
            LL k = charToLL(str),xorsum=0,ans = 0;
            for(int i=1;i<=n;i++){
                scanf("%s",str);
                LL x = charToLL(str);
                xorsum^=x;
                if(xorsum==k&&i>=A&&i<=B) ans++;
                ans+=binary(k^xorsum,i);
                mp[xorsum].push_back(i);
            }
            printf("Case %d: %lld
    ",t++,ans);
        }
    }
     
  • 相关阅读:
    iOS 开发小记 (五)
    ReentrantLock API
    多线程之生产者消费者
    maven私服的项目使用配置
    maven仓库nexus安装配置
    thymeleaf自定义标签方言处理
    关于svn更新失败,clearup异常解决
    shiro+spring
    日常遇到的小问题
    springmvc控制器controller单例问题
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5765384.html
Copyright © 2020-2023  润新知