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(n-k+1)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include <iostream>
#include<vector>
#define MAXN 1000050
#define lson i<<1
#define rson i<<1|1
#define LL long long
using namespace std;
char s[MAXN];
char a[MAXN];
int p[MAXN];
int ans[MAXN];
int tmp[MAXN];
int main() {
	int n, m;
	scanf(" %s", s);
	n = strlen(s);
	scanf("%d", &m);
	for (int i = 0; i < m; ++i) {
		int k, d;
		scanf("%d%d", &k, &d);
		for (int i = 0; i < n; ++i)
			p[i] = ans[i] = i;
		int cid = 0;
		for (int x = 0; x < d; ++x)
			for (int j = x; j < k; j += d)
			{
				p[cid++] = j;
			}
		int last = p[0];
		for (int j = 0; j <n-1;++j)
			p[j] = p[j + 1];
		p[n-1] = last;
		int x = n - k + 1;
		while (x) {
			if (x & 1) {
				for (int j = 0; j < n; ++j)
					tmp[j] = ans[p[j]];
				for(int j=0;j<n;++j)
					ans[j]=tmp[j];
			}
			for (int j = 0; j < n; ++j)
				tmp[j] = p[p[j]];
			for (int j = 0; j < n; ++j)
				p[j] = tmp[j];
			x >>= 1;
		}
		for (int j = 0; j < n; ++j)
		{
			a[j] = s[ans[(j + k - 1) % n]];
		}
		for (int j = 0; j < n; ++j)
			s[j] = a[j];
		printf("%s\n", s);
	}
}

  

时间: 2024-10-11 16:43:51

codeforces 484C Strange Sorting Codeforces Round #276 (Div. 1) C的相关文章

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> #

Codeforces Round #276 (Div. 1)

Codeforces 484 A. Bits 做题感悟:这题不难,是一个构造题,找一下规律就好. 解题思路: 假如两个数的二进制位数分别是 a ,b.(这里假设 a < b)  , 当 b - a >= 1 时只有两种情况可以选择 (1 << b) - 1  or  (1<<a) -1  ,这里当然先判断前一个是否满足,当 a = b 的时候,枚举两个数的每一位,如果出现小的数当前位为 0 ,且大的数当前位为 1 ,那么也有两种情况选择要么当前位加上后面的所有位都为 1

Codeforces Round #276 (Div. 1) A. Bits 贪心

A. Bits Let's denote as  the number of bits set ('1' bits) in the binary representation of the non-negative integer x. You are given multiple queries consisting of pairs of integers l and r. For each query, find the x, such that l ≤ x ≤ r, and is max

Codeforces Round #276 (Div. 2)C. Bits(构造法)

这道题直接去构造答案即可. 对于l的二进制表示,从右到左一位一位的使其变为1,当不能再变了(再变l就大于r了)时,答案就是l. 这种方法既可以保证答案大于等于l且小于等于r,也可以保证二进制表示时的1最多. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include&l

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

Codeforces Round #276 (Div. 2)D - Maximum Value(筛法)

就是一种筛法思想的应用. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<algorithm> #include<

Codeforces Round #276 (Div.1) Solution

水平越来越菜了 A  水题,注意后面全是1的情况 B  调和级数呀.把倍数全部扫一遍.一个数是多个数的倍数的话肯定是大的比较优.然后可以用two pointer扫一下. C  就是一个置换群,把轮换找出来就好了.傻逼的写了好久. D  有意思的傻逼DP,容易得到dp[i] = max{dp[j] + max{abs(a[k]-a[h])}} .只要更新一个U = max{a[i] + max_{0~(i-1)}{dp[i]}}和D = max{-a[i] + max_{0~(i-1)}{dp[i

Codeforces Round #276 (Div. 2)A. Factory(数论)

这道题可以暴力的一直按要求的方法去做,做1000000次还不能整除m就认为永远不能整除m了(m不超过100000,循环1000000次比较安全了已经).这种方法可以AC. 下面深入的分析一下到底循环多少次就可以确定结果:首先有这样一个规律:(a+b)%c=(a%c+b%c)%c,那么这样其实这道题每次就是2*a.官方题解说的好: Production will stops iff exists integer K ≥ 0 such a·2K is divisible by m. From thi

Codeforces Round #276 (Div. 1)Maximum Value

题意很好理解,就是让你搞到两个数a[i],a[j]使得a[i]>a[j]且a[i]%a[j]最大,然后把最大值输出来. 然后,我就开始乱搞了,时间复杂度有点高,O(n*sqrt(max(a[i])); 很容易得出一个结论 如果a[i]>a[j]且a[i]/p==a[j]/p那么a[j]%p>a[j]%p. 那么就开始乱搞了枚举p,如果全部枚举了复杂度就变成O(n*max(a[i]))了. 我们可以只枚举p*p<a[i]的部分,剩下的肯定是连续的1.2.3.4...p.语文不好,不知