week2 high precision + prefix and + difference

1, High precision operation (all positive numbers)

1. High precision addition (large number + large number)

2. High precision subtraction (large number - large number)

3. High precision multiplication (large number * decimal)

4. High precision division (large / decimal)

2, Prefix and

1. One dimensional prefix sum

2. Two dimensional prefix sum (sum of small matrices)

3, Difference

1. One dimensional difference

2. Two dimensional difference

1. High precision addition

Template:

#include<iostream>
#include<string>
#include<vector>
using namespace std;
const int N=1e6+10;
vector<int> add(vector<int> &A,vector<int> &B)
{
	int t=0;
	vector<int> C;
	for(int i=0;i<A.size()||i<B.size();i++)
	{
		if(i<A.size())
			t+=A[i];
		if(i<B.size())
			t+=B[i];
		C.push_back(t%10);
		t/=10;
	}
	if(t>=1)
		C.push_back(t);
	return C;//The returned type is vector
}
int main()
{
	string a,b;
	vector<int>A,B;//A. B two containers
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)//a.size() the length of the string
		A.push_back(a[i]-'0');//Store the string in reverse order and add the value to the end of B
	for(int i=b.size()-1;i>=0;i--)
		B.push_back(b[i]-'0');
	vector<int> C=add(A,B);
	int len=C.size();//Length of final result
	for(int i=len-1;i>=0;i--)//Reverse order input also needs reverse order output
		cout<<C[i];
	cout<<endl;
	return 0;
}

2. High precision subtraction

Template

#include<iostream>
#include<string>
#include<vector>
using namespace std;
//First compare the size of the two numbers entered
bool cmp(string a,string b)
{
	if(a.length()!=b.length())
		return a.length()>b.length();
	for(int i=0;i<a.length();i++)
	{
		if(a[i]!=b[i])
			return a[i]>b[i];
	}
	return 1;//The two values are equal
}
vector<int> sub(vector<int> &A,vector<int> &B)
{
	int t=0;
	vector<int> C;
	for(int i=0;i<A.size();i++)
	{
		t=A[i]-t;//If it is currently borrowed, subtract 1; otherwise, subtract 0
		if(i<B.size())
			t-=B[i];
		C.push_back((t+10)%10);//When T < 0, the answer is t+10; otherwise, it is t. wonderful!!!
		if(t>=0)
			t=0;
		else
			t=1;
	}
	//Clear leading 0
	while(C.size()>1&&C.back()==0)//You can't delete until the last number is 0
		C.pop_back();//Delete the last number
	return C;
}
int main()
{
	string a,b;
	cin>>a>>b;
	vector<int>A,B;
	for(int i=a.size()-1;i>=0;i--)
		A.push_back(a[i]-'0');
	for(int i=b.size()-1;i>=0;i--)
		B.push_back(b[i]-'0');
	vector<int> C;
	//Judge the size of a and B and determine the sign
	if(cmp(a,b))
	{
		C=sub(A,B);
		for(int i=C.size()-1;i>=0;i--)
			cout<<C[i];
		cout<<endl;
	}
	else
	{
		C=sub(B,A);//Guaranteed large number - decimal
		cout<<'-';
		for(int i=C.size()-1;i>=0;i--)
			cout<<C[i];
		cout<<endl;
	}
	return 0;
}

3. High precision multiplication (large number * decimal)

(1) Idea: here is to calculate the smaller number as a whole, wonderful!!!

(1) Template

#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<int> mul(vector<int> &A,int b)
{
	int t=0;
	vector<int> C;
	for(int i=0;i<A.size()||t;i++)
	{
		if(i<A.size())
			t=t+b*A[i];
		C.push_back(t%10);
		t/=10;
	}
	while(C.size()>1&&C.back()==0)//Delete leading 0
		C.pop_back();//Delete the last one in container A
	return C;
}
int main()
{
	string a;
	int b;
	vector<int> A;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)
		A.push_back(a[i]-'0');
	vector<int> C=mul(A,b);
	for(int i=C.size()-1;i>=0;i--)
		cout<<C[i];
	cout<<endl;
}

4. High precision Division

Template

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> div(vector<int> &A,int b,int &r)//r remainder
{
	vector<int> C;
	//Here we need to calculate in reverse order, because the previous is stored in reverse order, but due to consideration
	//When addition, subtraction, multiplication and division may be used together, in order to avoid the trouble of input, the division is also input in reverse order.
	//But division is what we follow.
	for(int i=A.size()-1;i>=0;i--)
	{
		r=r*10+A[i];
		C.push_back(r/b);//The answers stored here in c are sequential
		r%=b;
	}
	reverse(C.begin(),C.end());//Although C is discharged in sequence, the output is in reverse order, so
	//Transpose C
	while(C.size()>1&&C.back()==0)
		C.pop_back();
	return C;
}
int main()
{
	string a;
	int b;
	vector<int> A;
	cin>>a>>b;
	for(int i=a.size()-1;i>=0;i--)
		A.push_back(a[i]-'0');
	int r=0;//First remainder 0
	vector<int> C=div(A,b,r);
	for(int i=C.size()-1;i>=0;i--)
		cout<<C[i];
	cout<<endl<<r<<endl;
}

2, Prefix and

1. One dimensional prefix sum: formula, sum[i]=sum[i-1]+a[i]; subscript i starts from 1.

2. Two dimensional prefix and

Idea:

Title: https://www.acwing.com/problem/content/798/ (sum of submatrix)

#include<iostream>
using namespace std;
const int M=1010;
int a[M][M],sum[M][M];
int main()
{
	int n,m,q;
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&a[i][j]);
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			//Prefix and; subtract the extra two small squares and add the subtracted small square
			sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];//Matrix prefix and
		}
	}
	while(q--)
	{
		int x1,y1,x2,y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		//Sum of small matrices = sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]
		printf("%d\n",sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1]);
	}
	return 0;
}

3, Difference

1. One dimensional difference

(1) Idea: let B1=A1,B2=A2-A1,...Bn=An-A(n-1), then An=B1+B2+...+Bn, call array B the difference of array a, and array a the prefix and sum of array B.

Function: if we want to add c to each number in array a [l,r], we can operate on array b. We only need b[l]+=c (we can add c to all numbers in array a from L), b[r+1]-=c (because we only need to add c to the numbers in [l,r], we also need to subtract c from the numbers after r), so we can add c to each number in array a [l,r].

Title: 797. Difference - AcWing question bank

#include<iostream>
using namespace std;
const int M=100010;
int a[M],b[M];
void insert(int l,int r,int c)//Construct differential array
{
	//We just need to add c to the number in [l,r], so we just need to add it here to the following number.
	b[l]+=c;
	b[r+1]-=c;
}
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		insert(i,i,a[i]);//Here, the construction of the difference group can be regarded as adding a[i] to [i,i]
	while(m--)
	{
		int l,r,c;
		scanf("%d%d%d",&l,&r,&c);
		insert(l,r,c);
	}
	for(int i=1;i<=n;i++)
		b[i]+=b[i-1];//Find the prefix sum of the difference fraction group
	for(int i=1;i<=n;i++)
		printf("%d ",b[i]);//Each b[i] corresponds to the value of a[i]
	return 0;
}

2. Two dimensional difference

Idea: it first inserts the original array into the difference group b one by one, then modifies it on the difference array, and finally obtains the original array by calculating the prefix sum of the difference group. The prefix sum of the difference array corresponds to the subscript of the original array one by one. Two dimensional difference: make a[i][j] the prefix sum of array b[i][j], that is, b[i][j] is a[i][j] Therefore, you can modify the value of a b[i][j] (before the prefix and) to affect all subsequent values.

Title: https://www.acwing.com/problem/content/800/

#include<iostream>
using namespace std;
const int M=1010;
int a[M][M],b[M][M];
void insert(int x1,int y1,int x2,int y2,int c)//Construct two-dimensional difference
{
	b[x1][y1]+=c;
	b[x2+1][y1]-=c;
	b[x1][y2+1]-=c;
	b[x2+1][y2+1]+=c;
}
int main()
{
	int n,m,q;
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			scanf("%d",&a[i][j]);
			insert(i,j,i,j,a[i][j]);
		}
	}
	while(q--)
	{
		int x1,y1,x2,y2,c;
		scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&c);
		insert(x1,y1,x2,y2,c);//Insert the number first and add the inserted number to an element in the difference group b
	}
	//Finally, find the prefix sum
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			b[i][j]+=b[i][j-1]+b[i-1][j]-b[i-1][j-1];
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			printf("%d ",b[i][j]);
		}
		printf("\n");
	}
	return 0;
}

Title:

1,https://codeforces.com/problemset/problem/1455/B

Idea: you can find that sum=1+2+3+4+...+k. when you retreat in the first step, sum-2, and when you retreat in the second step, sum-3. Therefore, you can find that if you choose to retreat in any step, there can always be sum-x (x > 1). Therefore, you only need to compare the relationship between sum and n.

#include<iostream>
using namespace std;
int main()
{
	int t,n;
	cin>>t;
	while(t--)
	{
		cin>>n;
		int sum=0,k=0;//k to record the steps taken
		while(sum<n)
		{
			sum+=(++k);
		}
		if(sum==n)//Just arrived, no retreat
			cout<<k<<endl;
		else if(sum==n+1)//I've just taken a step, so I just need to take a step back to return to the template point
			cout<<k+1<<endl;
		else//This is because the value of sum can be sum-2, sum-3, sum-4,... Sum-g
			//So no matter how many steps you take, you can change the previous step to go back, so
			//The number of steps is unchanged.
			cout<<k<<endl;
	}
	return 0;
}

2,https://codeforces.com/problemset/problem/1541/B
Given an integer array, find the number of (i,j) satisfying the subscript I < J and a[i]*a[j]=i+j.
Idea: firstly, we can find that the value range of i+j is [3,2*n-1], that is, the range of a[i]*a[j] is [3,2*n-1], so find out all factors X in this range, and X is a[i], so we can get a[j]. Then judge whether a[i],a[j] exists and a[i]*a[j]==i+j. at the same time, we should note that when looking for factors, we will find that a[i]==a[j], so we also need to add the condition of a[i]!=a[j] (subject requirements) .
This problem is to find these two numbers from the product result first. As long as one number is determined, the other number can also be determined.

#include<iostream>
#include<algorithm>
#define M 200005
using namespace std;
int main()
{
    int t,n,a[M];
    scanf("%d",&t);
    while(t--)
    {
        //memset(a,0,sizeof(a));
        for(int i=0;i<M;i++)
            a[i]=0;
        long long ans=0;
        scanf("%d",&n);
        for(int i=1,x;i<=n;i++)
        {
            scanf("%d",&x);
            a[x]=i;//At the same time, record the subscript corresponding to the value
        }
        for(int i=3;i<=2*n-1;i++)//The range of i+j, that is, the range of a[i]*a[j]
        {
            for(int j=1;j*j<=i;j++)//Find the factor of i
            {
                if(i%j==0)//If j is a factor of i, another factor can also be determined
                {
                    int x=i/j;
                    if(a[x]&&a[j]&&a[x]+a[j]==i&&x!=j)//x. J exists and meets the formula requirements of the topic
                        ans++;
                }
                else
                    continue;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}


3,https://codeforces.com/problemset/problem/466/A
Idea: compare the price a*m of M tickets bought alone and the price b of M tickets bought together to decide whether to buy separately or together. If it is cheaper to buy together, calculate how many copies of M can be bought together, and then compare the remaining less than m tickets to whether to buy alone or at the group purchase price of M tickets (this step was ignored at the beginning).
 

#include<iostream>
using namespace std;
int main()
{
    int n,m,a,b,sum;
    cin>>n>>m>>a>>b;
    if(m*a<=b)
    {
        sum=n*a;
    }
    else
    {
        sum=n/m*b+(n%m*a>b?b:n%m*a);
    }
    cout<<sum<<endl;
    return 0;
}

4,Problem - 363B - Codeforces

Idea: use prefix sum to record the sum of all heights before each point and itself, and then traverse to find the minimum length with continuous length of K. sum[i]-sum[i-k] can get the sum of continuous K lengths in different places, and save the subscript of the minimum length.

#include<iostream>
using namespace std;
int sum[150005];
int main()
{
	int n,k,x;
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
	{
		cin>>x;
		sum[i]=sum[i-1]+x;
	}
	int min=sum[k],index=1;
	for(int i=k+1;i<=n;i++)
	{
		if(min>sum[i]-sum[i-k])
		{
			min=sum[i]-sum[i-k];
			index=i-k+1;
		}
	}
	printf("%d\n",index);
	return 0;
}


 

Tags: Algorithm

Posted on Sun, 31 Oct 2021 16:45:11 -0400 by badre