p1338如何开心的用map水题?

  这题其实不难啊,为啥没人写.

  理解完题意,首先预处理应该都会.然后考虑如何统计答案.直接想到一个暴力的方法:O(n^2)枚举左右端点,O(k)判断是否各个位置上的数都相同.

  然后考虑如何把一个n改成一个log(n)?k比较小,可以往这边考虑

  先考虑下面两个例子.这里每一位表示1,i时出现1的总数.

o[i].a[j]2 3 5  1
o[f].a[j]7 8 10 6

  这两个端点显然合法.如何描述这种"相同性"呢?我有两种方法.一种是都减去minn(a[j]),得到这样的结果.

都减1 1 2 4 0
都减6 1 2 4 0

  或者弄一个差分数组.原来是j∈[1,k],差分数组显然只需要[2,k]相同即可.

差分
? 1 2 -4

  然后如何更新答案呢?我想到了三行离散化.但是应该还有一种更好的方法:map.直接用结构体做下标还不是美滋滋?

using namespace std;
int i,f,tt;
int n,k,ans;
struct node{
    int a[40],sum[40];
    friend bool operator <(node x,node y){
        for(int d=2;d<=k;d++){
            if(x.a[d]!=y.a[d])
                return x.a[d]<y.a[d];
        }
        return 0;
    }
}o[100000];
map<node,int>mm;
int main()
{
    n=read();k=read();
    if(k==1){cout<<n;return 0;}
    mm[o[0]]=1;//记录全0的时候的下标为1
    for(i=1;i<=n;i++){
        tt=read();
        for(f=1;f<=k;f++){
            o[i].sum[f]=o[i-1].sum[f]+tt%2;
            tt=tt/2;
        }
        for(f=2;f<=k;f++)
            o[i].a[f]=o[i].sum[f]-o[i].sum[f-1];//差分数组
        tt=mm[o[i]];
        if(tt!=0) ans=max(ans,i-tt+1);//更新答案
        else      mm[o[i]]=i+1;//记录最先出现的下标.为了照顾o[0]只好赋为下标+1
    }
    cout<<ans;
    return 0;
}
日常推荐map
原文地址:https://www.cnblogs.com/qywyt/p/10266158.html