CF 444B(DZY Loves FFT-时间复杂度)
2015-09-08 19:26
411 查看
B. DZY Loves FFT
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
DZY loves Fast Fourier Transformation, and he enjoys using it.
Fast Fourier Transformation is an algorithm used to calculate convolution. Specifically, if a, b and c are
sequences with length n, which are indexed from 0 to n - 1,
and
We can calculate c fast using Fast Fourier Transformation.
DZY made a little change on this formula. Now
To make things easier, a is a permutation of integers from 1 to n,
and b is a sequence only containing 0 and 1.
Given a and b, DZY needs your help to calculate c.
Because he is naughty, DZY provides a special way to get a and b.
What you need is only three integers n, d, x.
After getting them, use the code below to generate a and b.
Operation x % y denotes remainder after division x by y.
Function swap(x, y) swaps two values x and y.
Input
The only line of input contains three space-separated integers n, d, x (1 ≤ d ≤ n ≤ 100000; 0 ≤ x ≤ 1000000006).
Because DZY is naughty, x can't be equal to 27777500.
Output
Output n lines, the i-th line should contain an integer ci - 1.
Sample test(s)
input
output
input
output
input
output
Note
In the first sample, a is [1 3 2], b is [1
0 0], so c0 = max(1·1) = 1, c1 = max(1·0, 3·1) = 3, c2 = max(1·0, 3·0, 2·1) = 2.
In the second sample, a is [2 1 4 5 3], b is [1
1 1 0 1].
In the third sample, a is [5 2 1 4 3], b is [1
1 1 1 0].
这题解法‘朴素’得难以置信
转载自http://codeforces.com/blog/entry/12959:
Firstly, you should notice that A, B are given randomly.
Then there're many ways to solve this problem, I just introduce one of them.
This algorithm can get Ci one
by one. Firstly, choose an s. Then check if Ci equals
to n, n - 1, n - 2... n - s + 1. If none of is the answer, just calculate Ci by
brute force.
The excepted time complexity to calculate Ci - 1 is
around
where
.
Just choose an s to make the formula as small as possible. The worst excepted number of operations is around tens of million.
对于每次询问:
先暴力枚举,看看答案在不在[n-s+1,n]中
否则暴力。
复杂度=O(s+(tot'0'/i)^s*tot'1')
(tot'0'/i)^s表示[n,n-s+1]中没有答案
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
DZY loves Fast Fourier Transformation, and he enjoys using it.
Fast Fourier Transformation is an algorithm used to calculate convolution. Specifically, if a, b and c are
sequences with length n, which are indexed from 0 to n - 1,
and
We can calculate c fast using Fast Fourier Transformation.
DZY made a little change on this formula. Now
To make things easier, a is a permutation of integers from 1 to n,
and b is a sequence only containing 0 and 1.
Given a and b, DZY needs your help to calculate c.
Because he is naughty, DZY provides a special way to get a and b.
What you need is only three integers n, d, x.
After getting them, use the code below to generate a and b.
//x is 64-bit variable; function getNextX() { x = (x * 37 + 10007) % 1000000007; return x; } function initAB() { for(i = 0; i < n; i = i + 1){ a[i] = i + 1; } for(i = 0; i < n; i = i + 1){ swap(a[i], a[getNextX() % (i + 1)]); } for(i = 0; i < n; i = i + 1){ if (i < d) b[i] = 1; else b[i] = 0; } for(i = 0; i < n; i = i + 1){ swap(b[i], b[getNextX() % (i + 1)]); } }
Operation x % y denotes remainder after division x by y.
Function swap(x, y) swaps two values x and y.
Input
The only line of input contains three space-separated integers n, d, x (1 ≤ d ≤ n ≤ 100000; 0 ≤ x ≤ 1000000006).
Because DZY is naughty, x can't be equal to 27777500.
Output
Output n lines, the i-th line should contain an integer ci - 1.
Sample test(s)
input
3 1 1
output
1 3 2
input
5 4 2
output
2 2 4 5 5
input
5 4 3
output
5 5 5 5 4
Note
In the first sample, a is [1 3 2], b is [1
0 0], so c0 = max(1·1) = 1, c1 = max(1·0, 3·1) = 3, c2 = max(1·0, 3·0, 2·1) = 2.
In the second sample, a is [2 1 4 5 3], b is [1
1 1 0 1].
In the third sample, a is [5 2 1 4 3], b is [1
1 1 1 0].
这题解法‘朴素’得难以置信
转载自http://codeforces.com/blog/entry/12959:
Firstly, you should notice that A, B are given randomly.
Then there're many ways to solve this problem, I just introduce one of them.
This algorithm can get Ci one
by one. Firstly, choose an s. Then check if Ci equals
to n, n - 1, n - 2... n - s + 1. If none of is the answer, just calculate Ci by
brute force.
The excepted time complexity to calculate Ci - 1 is
around
where
.
Just choose an s to make the formula as small as possible. The worst excepted number of operations is around tens of million.
对于每次询问:
先暴力枚举,看看答案在不在[n-s+1,n]中
否则暴力。
复杂度=O(s+(tot'0'/i)^s*tot'1')
(tot'0'/i)^s表示[n,n-s+1]中没有答案
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (100000+10) #define MAXX (1000000006+1) #define N_MAXX (27777500) long long mul(long long a,long long b){return (a*b)%F;} long long add(long long a,long long b){return (a+b)%F;} long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;} typedef long long ll; ll n,d,x; int i,a[MAXN],b[MAXN]; //x is 64-bit variable; ll getNextX() { x = (x * 37 + 10007) % 1000000007; return x; } void initAB() { for(i = 0; i < n; i = i + 1){ a[i] = i + 1; } for(i = 0; i < n; i = i + 1){ swap(a[i], a[getNextX() % (i + 1)]); } for(i = 0; i < n; i = i + 1){ if (i < d) b[i] = 1; else b[i] = 0; } for(i = 0; i < n; i = i + 1){ swap(b[i], b[getNextX() % (i + 1)]); } } int q[MAXN]={0},h[MAXN]={0}; int main() { // freopen("FFT.in","r",stdin); // freopen("FFT.out","w",stdout); cin>>n>>d>>x; initAB(); Rep(i,n) if (b[i]) q[++q[0]]=i; Rep(i,n) h[a[i]]=i; // Rep(i,n) cout<<a[i]<<' ';cout<<endl; // Rep(i,n) cout<<b[i]<<' ';cout<<endl; Rep(i,n) { int s=30,ans=0; Rep(j,30) { if (n-j<=0) break; int t=h[n-j]; if (t<=i&&b[i-t]) {ans=n-j; break;} } if (!ans) { For(j,q[0]) { int t=q[j]; if (t>i) break; ans=max(ans,a[i-t]*b[t]); } } printf("%d\n",ans); } return 0; }
相关文章推荐
- ThinkPHP中通过URL重写隐藏应用的入口文件index.php的相关服务器的配置
- ssh远程转发使远程主机在所有ip上监听
- 腾讯面试
- 杭电acm阶段之理工大版
- CString的split功能
- Leetcode|Median of Two Sorted Arrays
- dictionaryWithObjectsAndKeys
- cocos2d内存管理
- TTL门与COMS门区别
- 自定义分区标题不随着table滑动
- hdu 1102 Constructing Roads
- 2015多校联合第八场hdu5384Danganronpa AC自动机
- C++中extern “C”含义深层探索
- Unity3d C# Socket 下载文件 (同步到)
- 熟悉linux-安装tomcat
- Mac快速配置adb大法
- 46 Permutations
- [c#]记一次实验室局域网的ARP欺骗
- Web 服务编程,REST 与 SOAP
- 1.1 JavaScript高级程序设计(第3版) 笔记---对象