tyvj P2020 Rainbow 的信号 【位运算】

题目:

Freda发明了传呼机之后,rainbow进一步改进了传呼机发送信息所使用的信号。由于现在是数字、信息时代,rainbow发明的信号用N个自然数表示。为了避免两个人的对话被大坏蛋VariantF偷听T_T,rainbow把对话分成A、B、C三部分,分别用a、b、c三个密码加密。现在Freda接到了rainbow的信息,她的首要工作就是解密。Freda了解到,这三部分的密码计算方式如下:
在1~N这N个数中,等概率地选取两个数l、r,如果l>r,则交换l、r。把信号中的第l个数到第r个数取出来,构成一个数列P。
A部分对话的密码是数列P的xor和的数学期望值。xor和就是数列P中各个数异或之后得到的数; xor和的期望就是对于所有可能选取的l、r,所得到的数列的xor和的平均数。
B部分对话的密码是数列P的and和的期望,定义类似于xor和。
C部分对话的密码是数列P的or和的期望,定义类似于xor和。

 

分析:

(如果你想AC的话,请忽略此部分)

这个题的暴力其实很好打,直接进行无脑循环:(复杂度O(n^2)已经是优化过的了)

40分代码:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
long long n;
long long a[100010];
long long Xor[5000][5000],And[5000][5000],Or[5000][5000];
double ans1=0,ans2=0,ans3=0; 
long long cnt=0;

long long read() {
    long long ret=0,flag=1;
    char ch=getchar();
    while(ch<'0' || ch>'9') {
        if(ch=='-')
            flag=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9') {
        ret=ret*10+(long long)(ch-'0');
        ch=getchar();
    }
    return ret*flag;
}


int main()
{
    n=read();
    cnt=n*n;
    for(int i=1;i<=n;i++)
        a[i]=read();
    memset(Xor,0,sizeof(Xor));
    memset(And,0,sizeof(And));
    memset(Or,0,sizeof(Or));
    for(int i=1;i<=n;i++)
    {
        Xor[i][i]=a[i];
        ans1+=Xor[i][i];
        And[i][i]=a[i];
        ans2+=And[i][i];
        Or[i][i]=a[i];
        ans3+=Or[i][i];
    }
    for(int i=n-1;i>=1;i--)
        for(int j=i+1;j<=n;j++)
            {
                int p=(i+j)/2;
                Xor[i][j]=Xor[i][p]^Xor[p+1][j];    
                ans1+=Xor[i][j]*2;
            }
    for(int i=n-1;i>=1;i--)
        for(int j=i+1;j<=n;j++)
            {
                int p=(i+j)/2;
                And[i][j]=And[i][p]&And[p+1][j];    
                ans2+=And[i][j]*2;
            }
    for(int i=n-1;i>=1;i--)
        for(int j=i+1;j<=n;j++)
            {
                int p=(i+j)/2;
                Or[i][j]=Or[i][p]|Or[p+1][j];    
                ans3+=Or[i][j]*2;
            }
    printf("%.3lf %.3lf %.3lf\n",ans1/cnt,ans2/cnt,ans3/cnt);
    return 0;
}
View Code

 

 

而正解其实也不远了,通过分析这三种运算符的特点,只关心1的贡献:

(^):

1^1=0;

0^1=1;

他的功能就是:只要遇到1,就把当前的异或和取反,因此只要遇到1,就交换之前1和0的个数(即所有的1都变成了0,所有的0都变成了1)并且给1的个数加1;(自己应当拿笔模拟一下)

 

(&):

1&1=1;

1&0=0;

他的功能就是:只要遇到0,后面的都是0,因此只要找到前一个0出现的位置作为断点,计算有多少1出现就行了;

 

(|):

1|0=1;

1|1=1;

他的功能就是:只要遇到1,后面的都是1,因此只要找到前一个1出现的位置作为断点,计算有多少1出现就行了;

 

下面是参考代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
int n;
int cnt[2],last_pos[2];
int a[100005],b[100005];
double ans_or=0,ans_xor=0,ans_and=0;

void cal(int x)
{
    fill(cnt,cnt+2,0);
    fill(last_pos,last_pos+2,0);
    for(int i=1;i<=n;i++) b[i]=((a[i]>>x)&1);
    for(int i=1;i<=n;i++)
    {
        if(i!=1)
        {
            ans_xor+=(double)(1<<x)/n/n*cnt[!b[i]];
            if (b[i]==0) ans_or+=(double)(1<<x)/n/n*last_pos[1];    
            else
            {
                ans_or+=(double)(1<<x)/n/n*(i-1);
                ans_and+=(double)(1<<x)/n/n*(i-1-last_pos[0]);
            }  
        }
        last_pos[b[i]]=i;
        if(b[i]==0) cnt[0]++;
        else
            swap(cnt[0],cnt[1]),cnt[1]++;
    }
    for(int i=1;i<=n;i++)
    if(b[i])
    {
        double tmp=(double)(1<<x)/n/n/2;
        ans_xor+=tmp;
        ans_or+=tmp;
        ans_and+=tmp;
    }
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=0;i<=30;i++) cal(i);
    printf("%.3lf %.3lf %.3lf",ans_xor*2,ans_and*2,ans_or*2);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/linda-fcj/p/7218522.html

基于SSM框架的智能家政保洁预约系统,是一个旨在提高家政保洁服务预约效率和管理水平的平台。该系统通过集成现代信息技术,为家政公司、家政服务人员和消费者提供了一个便捷的在线预约和管理系统。 系统的主要功能包括: 1. **用户管理**:允许消费者注册、登录,并管理他们的个人资料和预约历史。 2. **家政人员管理**:家政服务人员可以注册并更新自己的个人信息、服务类别和服务时间。 3. **服务预约**:消费者可以浏览不同的家政服务选项,选择合适的服务人员,并在线预约服务。 4. **订单管理**:系统支持订单的创建、跟踪和管理,包括订单的确认、完成和评价。 5. **评价系统**:消费者可以在家政服务完成后对服务进行评价,帮助提高服务质量和透明度。 6. **后台管理**:管理员可以管理用户、家政人员信息、服务类别、预约订单以及处理用户反馈。 系统采用Java语言开发,使用MySQL数据库进行数据存储,通过B/S架构实现用户与服务的在线交互。系统设计考虑了不同用户角色的需求,包括管理员、家政服务人员和普通用户,每个角色都有相应的权限和功能。此外,系统还采用了软件组件化、精化体系结构、分离逻辑和数据等方法,以便于未来的系统升级和维护。 智能家政保洁预约系统通过提供一个集中的平台,不仅方便了消费者的预约和管理,也为家政服务人员提供了一个展示和推广自己服务的机会。同时,系统的后台管理功能为家政公司提供了强大的数据支持和决策辅助,有助于提高服务质量和管理效率。该系统的设计与实现,标志着家政保洁服务向现代化和网络化的转型,为管理决策和控制提供保障,是行业发展中的重要里程碑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值