51nod 1468 小Y的IP地址

来源:互联网 发布:ps cs6 for mac破解版 编辑:程序博客网 时间:2024/05/25 16:40

51nod 1468 小Y的IP地址

小Y最近在研究一个奇怪的16位IP系统
为了方便表示,我们可以将这个系统中的IP地址表示成16位二进制非负整数(既小于216 的非负整数),子网掩码表示成(2x1),x可能的取值是1到16(注意,和一般的子网掩码是不同的)。
现在小Y将随机生成一些IP地址,对于每一个IP地址小Y将做如下操作:
枚举每一个可能的子网掩码,对于任一子网掩码(设为X),我们将得到网络地址(设为Z)Z = (IP地址 and X)。(and是按位与操作)如果对于当前的IP地址,Z没有出现过,那么小Y将得到V[Z]的愉悦值,否则小Y得到0点愉悦值。这个IP地址可以给小Y带来的愉悦值是这些愉悦值的和。
例如,当IP地址为5时:
如果子网掩码为1, 则得到V[5 & 1] = V[1]点愉悦值
如果子网掩码为3, 因为5 & 3 = 1, 这个地址已经出现过了,不会得到愉悦值
如果子网掩码为7,则得到V[5 & 7] = V[5]点愉悦值
对于其他可能的子网掩码,Z都是5,因此都不会得到愉悦值
因此,IP地址为5时,小Y将得到V[1] + V[5]点愉悦值

小Y并不知道V数组,但对于每个随机生成出来的IP地址,小Y都会将他得到的愉悦值告诉你,现在小Y希望你还原一个可能的V数组

根据题目中的要求。对IP进行拆分。

IP=i=015ai2i,   ai=0  or   1

记IP对对应的愉悦值为:

H[IP]

有:

H[IP]=z=12161XzV[z]1

其实题中的H[IP]算是干扰项了。因为你会发现。任意的H数组。V都有可行解

1式的信息隐含在IP中。

我们把1式中的V[z]看作方程未知量 , Xz为系数

呢么对于IP从02161 每个IP都对应一个方程

并且是一个阶梯形。

因为XIP必然为1,并且有Xk=0 , k>IP

所以我们任意指定H[]数组都有解,当然 H[0]=0;

既然都有解。只要题中没有给出的H[IP] 。 我们就认为是 0

也就是说。我们已经拥有了一个合法的方程组了。

因为方程组是合法的.

也就是说。这样指定H[]数组必然不会出现矛盾。

那么我们认为所有H是以知的。前后没有矛盾的。

所以将所有H看作已知条件推导有:

V[k+2t]=H[k+2t]H[k]k<2t

虽然有些怀疑 。但他确实是对的。因为方程必有解。不管怎样。
都是从合法的方程推导来的

下面是C++代码

#include <stdio.h>#include <algorithm>#include <string.h>#include <queue>using namespace std;typedef long long LL;const int MAXN=(1<<16)+10;const LL INF=0x3f3f3f3f3f3f3f3f;LL H[MAXN];LL V[MAXN];int main (){    int n,IP;    LL h;    scanf("%d",&n);    for(int i=0;i<n;i++)    {        scanf("%d %lld",&IP,&h);        H[IP]=h;    }    V[0]=H[0];    V[1]=H[1];    for(int i=2,sz=1<<16,a=2,b=4;i<sz;i++)    {        if(i<b)        {            V[i]=H[i]-H[i-a];        }        else        {            b<<=1;            a<<=1;            V[i]=H[i]-H[i-a];        }    }    for(int i=0,sz=1<<16;i<sz;i++)        printf("%lld ",V[i]);    printf("\n");    return 0;}
原创粉丝点击