您的位置:首页 > 其它

16.7.15

2016-07-15 10:37 239 查看
gcd递归求最大公约数

int gcd(int a,int b)
{
if(a>=b)
return a%b==0?b:gcd(b,a%b);
else
return gcd(b,a);
}


RMQ区间最值查询(ST算法)(转载

RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j之间的最小/大值。对于该问题,最容易想到的解决方案是遍历,复杂度是O(n)。但当数据量非常大且查询很频繁时,该算法无法在有效的时间内查询出正解。

比较高效的算法是在线算法(ST算法)。所谓在线算法,是指用户每输入一个查询便马上处理一个查询。该算法一般用较长的时间做预处理,待信息充足以后便可以用较少的时间回答每个查询。ST(Sparse Table)算法是一个非常有名的在线处理RMQ问题的算法,它可以在O(nlogn)时间内进行预处理,然后在O(1)时间内回答每个查询。

首先DP预处理

设A[i]是要求区间最值的数列,F[i, j]表示从第i个数起连续2^j个数中的最大值。(DP的状态)

例如 A数列为:3 2 4 5 6 8 1 2 9 7

F[1,1] = max(3,2) = 3, F[1,2]=max(3,2,4,5) = 5,F[1,3] = max(3,2,4,5,6,8,1,2) = 8;

并且我们可以容易的看出F[i,0]就等于A[i]。(DP的初始值)

大区间可划分为左右两块小区间,状态转移方程为F[i, j]=max(F[i,j-1], F[i + 2^(j-1),j-1])。

状态转移方程的含义是:先更新所有长度为F[i,0]即1个元素,然后通过2个1个元素的最值,获得所有长度为F[i,1]即2个元素的最值,然后再通过2个2个元素的最值,获得所有长度为F[i,2]即4个元素的最值,以此类推更新所有长度的最值。

void RMQ(int num) //预处理->O(nlogn)
{
for(int j = 1; j < 20; ++j)
for(int i = 1; i <= num; ++i)
if(i + (1 << j) - 1 <= num)
{
maxsum[i][j] = max(maxsum[i][j - 1], maxsum[i + (1 << (j - 1))][j - 1]);
minsum[i][j] = min(minsum[i][j - 1], minsum[i + (1 << (j - 1))][j - 1]);
}
}


然后查询

假如我们需要查询的区间为(i,j),那么我们需要找到覆盖这个闭区间(左边界取i,右边界取j)的最小幂(可以重复,比如查询5,6,7,8,9,我们可以查询5678和6789)。

因为这个区间的长度为j - i + 1,所以我们可以取k=log2( j - i + 1),则有:RMQ(A, i, j)=max{F[i , k], F[ j - 2 ^ k + 1, k]}。

//—————

//今日代码

2016-07-15 personal training

A

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;

int main()
{
freopen("xx.in","r",stdin);
freopen("xx.out","w",stdout);

double l,p,q;
cin >> l >> p >> q;
double time = l/(p+q);
double len = p*time;
cout << len << endl;

return 0;
}


B

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;

int arr[500050];

int main()
{
freopen("xx.in","r",stdin);
freopen("xx.out","w",stdout);

int n;
cin >> n;
for(int i = 0; i < n; i++)
scanf("%d",&arr[i]);

int step = 0;
int L,R;
int l,r;
for(int i = 0; i < n-1; i++)
{
L = i,R = i;
while(arr[R]!=arr[R+1] && R < n-1) R++;
l = L+1,r = R-1;
int s = 0;
while(l<=r)
{
s++;
arr[l] = arr[L];
arr[r] = arr[R];
l++;
r--;
}
if(step<s) step = s;
}

cout << step<< endl;
cout << arr[0];
for(int i = 1; i < n; i++)
printf(" %d",arr[i]);
cout << endl;

return 0;
}


E

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;

LL mypow(double a,int b)
{
LL r = 1;
LL base = a;
while(b!=0)
{
if(b&1) r*=base;
base*=base;
b>>=1;
}
return r;
}

int main()
{
freopen("xx.in","r",stdin);
freopen("xx.out","w",stdout);

double n,X;
double m,Y;

cin >> n >> X;
double num;
LL ans1 = 0;
LL ans2 = 0;
for(int i = 0; i < n; i++)
{
cin >> num;
ans1+= num*mypow(X,n-i-1);
}
cin >> m >> Y;
for(int i = 0; i < m ; i++)
{
cin >> num;
ans2+= num*mypow(Y,m-i-1);
}

//  cout << ans1 <<endl<< ans2<<endl;
if(ans1==ans2) cout <<"=" << endl;
else if(ans1 > ans2) cout << ">" << endl;
else cout <<"<"<<endl;

return 0;
}


H

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;

int arr[10086];

int main()
{
freopen("xx.in","r",stdin);
freopen("xx.out","w",stdout);

for(int i = 1; i <=26; i++)
arr[i] = i;

int n,m;
cin >> n >> m;
string s;
cin >> s;
char c1,c2;
for(int i = 0;i < m; i++)
{
cin >> c1 >> c2;
for(int j = 1; j <= 26; j++)
{
if(arr[j] == c1-'a'+1) arr[j] = c2-'a'+1;
else if(arr[j] == c2-'a'+1) arr[j] = c1-'a'+1;
}
}

for(int i = 0; i < n; i++)
cout << (char)(arr[s[i]-'a'+1]+'a'-1);
cout << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: