一本通 分治专栏

方程f(x)的根(equation)

【问题描述】

求方程f(x)=2x+3x-4x=0在[1,2]内的根。

提示:2x可以表示成exp(x*log(2))的形式(需要含cmath库)。

【输入形式】

输入[1,2]的区间值。

【输出形式】

输出方程f(x)=0的根,x的值精确小数点10位。

【样例输入】

1 2
【样例输出】

1.5071105957

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

double l, r ,mid;
double check(double x){
   return exp(x*log(2)) + exp(x*log(3)) - exp(x*log(4)) ;


}
int main(){  
    //std::ios::sync_with_stdio(false);
    //cin.tie(0);
    //cout.tie(0);
    cin >> l >> r;
   
    while(abs(r-l) > 1e-4)
   {
        mid = (l + r) / 2;
    	if(check(mid) * check(l) <0 ) r = mid;
    	  else         l = mid;
       
        
	} 
	mid = (l + r ) / 2;
	printf("%.10lf",mid);
	return 0;
}

二分查找(binary)

【问题描述】

给出有n个元素的由小到大的序列,请你编程找出某元素第一次出现的位置。(n<=10^6)

【输入形式】

第一行:一个整数,表示由小到大序列元素个数;下面n行,每行一个整数;最后一行一个整数x,表示待查找的元素;

【输出形式】

如果x在序列中,则输出x第一次出现的位置,否则输出-1。

【样例输入】

5

3

5

6

6

7

6

【样例输出】

3

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int n , x , a[MAX];

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 0 ; i < n ; i ++ ) cin >> a[i];
    cin >> x;
    int l = 0 , r = n ;
   while(l < r){
    	 int mid = l + r >> 1;
    	 if(a[mid] >= x) r = mid ;
    	  else l = mid + 1;
	}
	if(a[l] == x) cout<<l + 1;
	 else cout<<-1;
	return 0;
}

求逆序对(deseq)

【问题描述】

给定一个序列a1,a2,…,an,如果存在iaj,那么我们称之为逆序对,求逆序对的数目。

【输入形式】

第一行为n,表示序列长度,接下来的n行,第i+1行表示序列中的第i个数。

【输出形式】

所有逆序对总数。

【样例输入】

4

3

2

3

2

【样例输出】

3

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int a[MAX],temp[MAX],n;
ll ans;
void mergesort(int l , int r){
 if(l>=r) return;
     int mid = l+r>>1;
     mergesort(l,mid);mergesort(mid+1,r);
     
      int i=l,k=l,j=mid+1;
    while(i<=mid && j<=r){
     	 if(a[i]<=a[j])  temp[k++] = a[i++];
		   else temp[k++] = a[j++],ans+=mid-i+1;
	 }

	while(i <= mid) temp[k++] = a[i++];
	while(j <= r) temp[k++] = a[j++];
	
	for(int i = l ; i <= r ; i ++ ) a[i] = temp[i];
	
	

}
int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 0 ; i < n ; i ++ ) cin >> a[i];
    mergesort(0,n-1);
    cout<<ans;
	return 0;
}

麦森数(mason)

一本通 分治专栏_第1张图片

输入格式
文件中只包含一个整数P(1000

输出格式
第一行:十进制高精度数2^P-12
p −1的位数。

第2-11行:十进制高精度数2^{P}-12
P−1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)

不必验证2^{P}-12
p −1与PP是否为素数。

#include
#include
#include
using namespace std;
int f[1001],p,res[1001],sav[1001];//乘法要开两倍长度
void result_1()
{
    memset(sav,0,sizeof(sav));
    for(register int i=1;i<=500;i+=1)
        for(register int j=1;j<=500;j+=1)
            sav[i+j-1]+=res[i]*f[j];//先计算每一位上的值(不进位)
    for(register int i=1;i<=500;i+=1)
    {
        sav[i+1]+=sav[i]/10;//单独处理进位问题,不容易出错
        sav[i]%=10;
    }
    memcpy(res,sav,sizeof(res));//cstring库里的赋值函数,把sav的值赋给res
}
void result_2()//只是在result_1的基础上进行了细微的修改
{
    memset(sav,0,sizeof(sav));
    for(register int i=1;i<=500;i+=1)
        for(register int j=1;j<=500;j+=1)
            sav[i+j-1]+=f[i]*f[j];
    for(register int i=1;i<=500;i+=1)
    {
        sav[i+1]+=sav[i]/10;
        sav[i]%=10;
    }
    memcpy(f,sav,sizeof(f));
}
int main()
{
    scanf("%d",&p);
    printf("%d\n",(int)(log10(2)*p+1));
    res[1]=1;
    f[1]=2;//高精度赋初值
    while(p!=0)//快速幂模板
    {
        if(p%2==1)result_1();
        p/=2;
        result_2();
    }
    res[1]-=1;
    for(register int i=500;i>=1;i-=1)//注意输出格式,50个换一行,第一个不用
        if(i!=500&&i%50==0)printf("\n%d",res[i]);
        else printf("%d",res[i]);
    return 0;
}

一元三次方程

【问题描述】

有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。

要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后2位。

【输入形式】

输入一行:a,b,c,d空格隔开。

【输出形式】

输出三个实根(根与根之间留有空格)

【样例输入】

1 -5 -4 20

【样例输出】

-2.00 2.00 5.00

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

double a,b,c,d,l,r,mid;
int ans;

double fun(double x){
	return a*x*x*x + b*x*x + c*x + d;
}


int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> a >> b >> c >> d;
    for(int i = -100 ;i <= 100 ;i++){
    	l = i ; r = i + 1;
    	double x1 = fun(l);
    	double x2 = fun(r);
    	if(!x1) {
    		  printf("%.2lf ",l);
    		  ans++;
		}
		if(x1*x2<0){
			   while(r-l>=1e-3){
			   	     mid = (l+r)/2;
			   	     if(fun(r) * fun(mid) <= 0)   l = mid;
			   	      else  r = mid;
			   } 
		   printf("%.2lf ",l);
    	   ans++; 
		}
		if(ans == 3) break;
	}
	return 0;
}


循环比赛

【问题描述】

设有m个选手进行循环比赛,其中n=2m,要求每名选手要与其他n-1名选手都赛一次,每名选手每天比赛一次,循环赛共进行n-1t天,要求每天没有选手轮空。

【输入形式】

输入m

【输出形式】

表格形式的比赛安排表,每个元素以空格隔开

【样例输入】

3
【样例输出】

1 2 3 4 5 6 7 8

2 1 4 3 6 5 8 7

3 4 1 2 7 8 5 6

4 3 2 1 8 7 6 5

5 6 7 8 1 2 3 4

6 5 8 7 2 1 4 3

7 8 5 6 3 4 1 2

8 7 6 5 4 3 2 1

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 
int n ;
int a[105][105];

void dfs(int l , int r ,int x){
	 if(x == 1) return ;

     a[l+x/2][r+x/2] = a[l][r];
     a[l+x/2][r] = a[l][r+x/2] = a[l][r]+x/2;
	 dfs(l,r+x/2,x/2);
	 dfs(l+x/2,r,x/2);
	 dfs(l,r,x/2);
	 dfs(l+x/2,r+x/2,x/2);
}
int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    n = pow(2,n);
    a[1][1] = 1;
    dfs(1,1,n);
    for(int i = 1 ; i <= n ; i ++ ){
    	 for(int j = 1; j <= n ; j ++)
    	  cout<<a[i][j]<<" ";
    	cout<<"\n";
	}
	return 0;
}

取余运算

【问题描述】

输入b,p,k的值,求bp mod k的值,其中b、p、k*k为长整型。

【输入形式】

【输出形式】

【样例输入】

2 10 9

【样例输出】

2^10 mod 9=7

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 
ll b,p,k;

ll quick(ll a, ll b ,ll mod){
	ll res = 1;
	while(b){
		if(b&1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res % mod;
}

int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> b >> p >> k;
    printf("%lld^%lld mod %lld=%lld",b,p,k,quick(b,p,k)); 
	return 0;
}

黑白棋子的移动

【问题描述】

有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况:

○○○○○●●●●●

移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:

○●○●○●○●○●

任务:编程打印出移动过程。

【输入形式】

一个整数n(n<=50)

【输出形式】

若干行,表示初始状态和每次移动的状态,用"o"表示白子,“x"表示黑子,”-"表示空行。

【样例输入】

7
【样例输出】

step 0:ooooooo*******–

step 1:oooooo–*****o

step 2:oooooo******–o*

step 3:ooooo–*****oo

step 4:ooooo*****–oo

step 5:oooo–*ooo

step 6:oooo****–ooo*

step 7:ooo–oooo*

step 8:oooo**–ooo*

step 9:o–o**ooooo*

step 10:ooo*–oooo

step 11:–ooooooo*

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

char c[105];
int n ,s,ans;
void print(){
	cout<<"step "<<ans<<":";
	for(int i = 1 ;i <= 2*n + 2 ; i ++ ) cout<<c[i];
	cout<<"\n";
	ans++;
}
void move(int k){
	for(int i = 0 ; i <= 1 ; i++ ) c[s+i] = c[k + i], c[k + i] = '-';
	s = k;
	print();
}
void mv(int n){
	int i,k;
	if (n==4)                
	{
		move(4); 
		move(8);
		move(2);
		move(7);
		move(1);
	}
	else
	{
		move(n);
		move(2*n-1);
		mv(n-1);
	}
}
int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    s = 2*n+1;
    for(int i = 1 ; i <= n ; i++) c[i] = 'o';
    for(int i = n+1 ;i <= 2*n ;i++ ) c[i] = '*';
    c[2*n+1] = c[2*n+2] = '-';
    print();
    mv(n);
	return 0;
}

光荣的梦想

【问题描述】

Prince对他在这片大陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平衡是个梦想。因为有很多奇异的物种拥有各种不稳定的能量,平衡瞬间即被打破。KB决定求助于你,帮助他完成这个梦想。
  一串数列即表示一个世界的状态。
  平衡是指这串数列以升序排列。而从一串无序数列到有序数列需要通过交换数列中的元素来实现。KB的能量只能交换相邻两个数字。他想知道他最少需要交换几次就能使数列有序。

【输入形式】

第一行为数列中数的个数n,第二行为n <= 10000个数。表示当前数列的状态。

【输出形式】

输出一个整数,表示最少需要交换几次能达到平衡状态。

【样例输入】

4

2 1 4 3

【样例输出】

2

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
# include
# include
# include
# include
# include
# include
# include 
# include
# include
# include 
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int > PII; 
const int mod=1e9+7;
const int MAX=2e6+10;
const int Time=86400;
const int X=131;
const int inf=0x3f3f3f3f;
const double PI = 1e-4;
double pai = 3.14159265358979323846; 

int a[MAX],temp[MAX],n;
ll ans;
void mergesort(int l , int r){
 if(l>=r) return;
     int mid = l+r>>1;
     mergesort(l,mid);mergesort(mid+1,r);
     
      int i=l,k=l,j=mid+1;
    while(i<=mid && j<=r){
     	 if(a[i]<=a[j])  temp[k++] = a[i++];
		   else temp[k++] = a[j++],ans+=mid-i+1;
	 }

	while(i <= mid) temp[k++] = a[i++];
	while(j <= r) temp[k++] = a[j++];
	
	for(int i = l ; i <= r ; i ++ ) a[i] = temp[i];
	


}
int main(){  
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 0 ; i < n ; i ++ ) cin >> a[i];
    mergesort(0,n-1);
    cout<<ans;
	return 0;
}

你可能感兴趣的:(一本通)