Toj 3016 Decode the Strings

题目标签:分治(矩阵快速幂)

题目描述:对一个长度为n的字符串A,按照以下方式对其进行加密m次,得到另一个字符串B,现在给你n,m,B,求原串A。加密方式:给出一个1~n这n个数字的排列p[i],加密一次后的串B[i]=A[p[i]]。

思路:由于m很大,则 1. 有很短的循环节 or 2. 复杂度log n。一开始使用1,但是我没找到好的方法,至今不知道是否可解。由于个人问题,2也很让我费解,但事实确是如此,把p[i]转化成一个矩阵M,加密m次就相当于M^m,然后观察是否可以从M^m得到关于A串的信息。

我转化的过程是这样的:若p[i] = t,则M[i][t] = 1,其它位置均为0。很明显M是一个稀疏矩阵,每行、每列有且只有一个数,令M.a[i]表示第i行第几个是1(后来发现还可以表示第i个是1的是第几列,节省了部分空间),M.b[i]表示(第i个是1的是第几行(后来发现还可以表示第i列第几个是1)。这样表示矩阵让我们更难理解,但让O(n^3)的矩阵乘法降到了O(n),也是值得的。

之后只需要对矩阵进行快速幂就行啦,假设最后得到的矩阵为T,则T.a[i]是用来加密的,T.b[i] 是用来解密的。本人对这个题的理解还不是非常清晰,如果有任何疏漏的地方,欢迎各位提出宝贵意见。

code:

#include<iostream>
#include<string.h>
#include<string>
using namespace std;
class Mat
{
public:
    int n,a[82],b[82];
    Mat()
    {
        n=0;
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
    }
    Mat operator * (Mat &M)
    {
        Mat ans;
        ans.n=n;
        for(int i=1;i<=n;i++)
        {
            ans.a[i]=M.a[a[i]];
            ans.b[ans.a[i]]=i;
        }
        return ans;
    }
};
Mat POW(Mat R,int m)
{
    if(m==1)return R;
    Mat P=POW(R,m/2);
    P=P*P;
    if(m%2==0)return P;
    return P*R;
}
int main()
{
    int n,m,t;
    string str;
    while(cin>>n>>m&&n)
    {
        Mat M;
        M.n=n;
        for(int i=1;i<=n;i++)
        {
            cin>>t;
            M.a[i]=t;
            M.b[t]=i;
        }
        cin.get();
        getline(cin,str);
        M=POW(M,m);
        for(int i=1;i<=n;i++)cout<<str[M.b[i]-1];
        cout<<endl;
    }
    return 0;
}


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值