Codeforces 484C Strange Sorting(置换)

题目链接:Codeforces 484C Strange Sorting

题目大意:给定一个长度为N的字符串,现在有M次询问,每次要从左向右逐个对长度为K的子串进行D-sorting,最后

输出生成的串。

解题思路:问题即为一个置换的思想,L对应的左移一位的置换,C对应的是D-sorting前K为的置换,每次执行完一次C

肯定执行一下L,保证D-sorting的为不同的K长度子串。用类似矩阵快速幂的思想对字符串进行求解,最后在有循环移

动对应的N-K位。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 1e6+5;

int N, M, K, D, L[maxn];
int C[maxn], P[maxn], x[maxn], tmp[maxn];
char str[maxn];

void multi () {
    for (int i = 0; i < N; i++) tmp[i] = x[x[i]];
    for (int i = 0; i < N; i++) x[i] = tmp[i];
}

int main () {
    scanf("%s%d", str, &M);
    N = strlen(str);
    for (int i = 0; i < N; i++)
        L[i] = (i ? i - 1 : N - 1);

    while (M--) {
        scanf("%d%d", &K, &D);

        for (int i = 0; i < N; i++) C[i] = i;
        int mv = 0;
        for (int i = 0; i < D; i++) {
            for (int j = i; j < K; j += D)
                C[j] = mv++;
        }
        for (int i = 0; i < N; i++) P[i] = C[i];
        for (int i = 0; i < N; i++) x[i] = C[L[i]];

        int n = N - K;
        while (n) {
            if (n&1) {
                for (int i = 0; i < N; i++)
                    P[i] = x[P[i]];
            }
            multi();
            n >>= 1;
        }

        for (int i = 0; i < N; i++) tmp[P[i]] = str[i];
        for (int i = 0; i < N; i++) str[(i + (N - K)) % N] = tmp[i];
        printf("%s\n", str);
    }
    return 0;
}
时间: 2025-01-31 03:48:57

Codeforces 484C Strange Sorting(置换)的相关文章

codeforces 484C Strange Sorting Codeforces Round #276 (Div. 1) C

思路:首先 他是对1到k 元素做一次变换,然后对2到k+1个元素做一次变化....依次做完. 如果我们对1到k个元素做完一次变换后,把整个数组循环左移一个.那么第二次还是对1 到 k个元素做和第一次一样的变换,再左移,再对1 到 k个元素做和第一次一样的变换,依次做完n-k+1即可. 假设题目要求的变换为C    循环左移变换为P.那么对于每次查询 相当于做  n-k+1  (CP) 变换.最后把答案再向右移动n-k+1  回到原来位置即可. 那么问题就解决了   效率    每次查询n log

Codeforces Round #425 (Div. 2) Problem C (Codeforces 832C) Strange Radiation - 二分答案 - 数论

n people are standing on a coordinate axis in points with positive integer coordinates strictly less than 106. For each person we know in which direction (left or right) he is facing, and his maximum speed. You can put a bomb in some point with non-n

Codeforces 832C - Strange Radiation

832C - Strange Radiation 思路:二分最短时间. 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mp make_pair #define pi acos(-1.0) #define pii pair<int,int> #define pil pair<int,long> #define mem(a,

Codeforces 911E - Stack Sorting

911E - Stack Sorting 思路: 用栈来模拟,能pop就pop,记下一个需要pop的数为temp,那么如果栈非空,栈顶肯定大于temp,那么加入栈 栈顶值-1 到 temp 的值,否则加入栈 n 到 1 的值,如果需要加入的数之前已经出现过,答案则不存在. 代码: #include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define meme(a,b) mem

CodeForces 830B - Cards Sorting

将每个数字的位置存进该数字的vector中 原数组排个序从小到大处理,每次在vector里二分找到距离当前位置“最远”的位置(相差最大),更新答案 树状数组维护每个数字现在的位置和原位置之差 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 const int N = 100005; 5 int n; 6 int a[N], b[N]; 7 vector<int> v[N]; 8 i

AGC014-F Strange Sorting

题意 \(n\)-排列,反复进行:将序列中为前缀最大值的数全部移动到序列末(两种数不改变相对位置),问经过多少次后第一次全部升序排列 做法 定义:用high表示为前缀最大值,low则反之 考虑忽略\(1\),那么\([2,n]\)相对排好序后,假设用了\(T\)次,如果\(1\)在首,则答案为\(T\),否则还要在进行一次,为\(T+1\) 检查答案是\(T\)还是\(T + 1\)? \(T = 0\)的情况非常简单 假设\(T> 0\),并考虑\(T ? 1\)运算后序列的状态 令\(f\)

第二十次codeforces竞技结束 #276 Div 2

真是状况百出的一次CF啊-- 最终还Unrated了,你让半夜打cf 的我们如何释怀(中途茫茫多的人都退场了)--虽说打得也不好-- 在这里写一下这一场codeforces的解题报告,A-E的 题目及AC代码,部分题目有简单评析,代码还算清晰,主要阅读代码应该不难以理解. Questions about problems # Author Problem When Question Answer       2014-11-05 21:24:38 Announcement General ann

【AtCoder】AGC014

AGC014 链接 A - Cookie Exchanges 发现两个数之间的差会逐渐缩小,所以只要不是三个数都相同,那么log次左右一定会得到答案 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter

AtCoder Grand Contest 014

AtCoder Grand Contest 014 A - Cookie Exchanges 有三个人,分别有\(A,B,C\)块饼干,每次每个人都会把自己的饼干分成相等的两份然后给其他两个人.当其中有一个人的饼干数量是奇数的时候停止,求会进行几次这样子的操作,或者会永远进行下去. 首先无解的情况一定是三个数都是相等的偶数. 否则直接暴力模拟就行了.(盲猜答案不会很大) 证明一下答案的范围:不妨令\(A\le B\le C\),那么最大值和最小值之间的差就是\(C-A\),那么执行完一次操作之后