C++ 颠倒循环移位的顺序

C++ 颠倒循环移位的顺序,c++,algorithm,decoding,rmq,lowest-common-ancestor,C++,Algorithm,Decoding,Rmq,Lowest Common Ancestor,这是我很难解决的问题 给您一个密文Y和一系列循环移位,这些移位从字符串Z生成Y,带有参数(i,j,k)的移位应用于子字符串Z[i..j](从第i个字符到第j个字符,包括在内),并循环将其向右旋转k次。字符串从一开始编号。根据以上信息,您的任务是猜测初始明文X 输入: 第一行包含密文,它是由N个小写英文字母(1)组成的非空字符串≤ N≤ 50000). 第二行包含移位数M(1≤ M≤ 50000). 以下M行描述了循环移位的顺序(按照其应用于明文的顺序)。每个移位由三个参数i、j、k(1)描述≤

这是我很难解决的问题

给您一个密文Y和一系列循环移位,这些移位从字符串Z生成Y,带有参数(i,j,k)的移位应用于子字符串Z[i..j](从第i个字符到第j个字符,包括在内),并循环将其向右旋转k次。字符串从一开始编号。根据以上信息,您的任务是猜测初始明文X

输入:

第一行包含密文,它是由N个小写英文字母(1)组成的非空字符串≤ N≤ 50000). 第二行包含移位数M(1≤ M≤ 50000). 以下M行描述了循环移位的顺序(按照其应用于明文的顺序)。每个移位由三个参数i、j、k(1)描述≤ i 输入示例:

logoduck 
3
1 3 1 
4 5 1 
1 4 1
作为输出,您应该提供解密文本(例如“goodluck”)

显而易见的方法是尝试从最后一个班次开始扭转每一个班次。这种方法似乎没有时间效率。然而,我想不出任何其他方法来做这件事,所以任何帮助都是非常感谢的

我附上我的代码:

#include <iostream>
#include <vector>
#include <string>


int main() {

    std::string message;
    std::cin >> message;

    int number_of_elements = message.size();
    int elements[number_of_elements];
    for (int i = 0; i < number_of_elements; ++i) {
        elements[i] = i;
    }

    int number_of_shifts;
    std::cin >> number_of_shifts;
    std::vector<std::vector<int>> shifts(number_of_shifts);

    for (int iterator = 0; iterator < number_of_shifts; ++iterator) {
        int left, right, by;
        std::cin >> left >> right >> by;
        --left;
        --right;
        shifts[iterator].push_back(left);
        shifts[iterator].push_back(right);
        shifts[iterator].push_back(by);
    }

    for (int iterator = number_of_shifts - 1; -1 < iterator; --iterator) {
        int current[number_of_elements];
        int left, right, by;
        left = shifts[iterator][0];
        right = shifts[iterator][1];
        by = shifts[iterator][2];


        for (int j = right; left - 1 < j; --j) {
            if (j - by < left) {
                current[right + 1 - (left - (j - by))] = elements[j];
            } else {
                current[j - by] = elements[j];
            }
        }

        for (int j = left; j < right + 1; ++j) {
            elements[j] = current[j];
        }
    }

    for (int i = 0; i < number_of_elements; ++i) {
        std::cout <<  message.substr(elements[i], 1);
    }

    return 0;
}
#包括
#包括
#包括
int main(){
std::字符串消息;
std::cin>>消息;
int number_of_元素=message.size();
int元素[元素的数量];
for(int i=0;i<元素的个数;++i){
元素[i]=i;
}
整数移位数;
std::cin>>换班次数;
std::向量移位(移位的数量);
for(int迭代器=0;迭代器<移位数;++迭代器){
int left,right,by;
标准::cin>>左>>右>>由;
--左;
--对,;
移位[迭代器]。向后推(左);
移位[迭代器]。向后推(右);
移位[迭代器]。推回(按);
}
for(int迭代器=移位次数-1;-1<迭代器;--迭代器){
int当前[元素的数量];
int left,right,by;
左=移位[迭代器][0];
右=移位[迭代器][1];
by=移位[迭代器][2];
对于(int j=右;左-1
当然,可以通过这些操作构建旋转

实现是一个二叉树、B树或类似的树,叶中的字符串大小有限


不难找到C++实现,但不幸的是,STL没有一个。如果你必须自己实现,那就有点棘手。

[OT]:你可以用<代码> STD::向量< /代码>代替<代码> STD::vector < /COD>。不存在额外的内存(<代码> int流[NoMyByOfOntEng];< /> >无效BTW,VLA扩展)@Jarod42谢谢你的建议!不过,这不会改变复杂性,对吧?你应该仍然在
O(N*M)
,但因子可能很重要。(你有1个分配而不是M)谢谢,我会试试这个!