multiway merge
62 ugly number
Title Link: Acwing 62 ugly number
146. Sequence
Title Link: acwing 146 sequence
Question meaning: m arrays, n numbers per array. Now in M arrays, each array selects an array into n sequences, with a total width of n m n^m nm selection, find the minimum sum of the first n sequences
Analysis: This is a very classic binary heap problem. I often encounter it. I use the idea of multi-channel merging. Now there are m sequences to be merged. Find the minimum n numbers in front. If there is violence, it will definitely be TLE, so I don't require all of them to be solved by heap
General idea: now m sequences are merged, which is simplified to every two sequences. Find the first n terms of the sum of the two sequences. Observe the following combination to find a property
a
1
,
a
2
,
a
3
,
...
...
,
a
n
a_1,a_2,a_3,......,a_n
a1,a2,a3,......,an
b
1
,
b
2
,
b
3
,
...
...
,
b
n
b_1,b_2,b_3,......,b_n
b1,b2,b3,......,bn
Then we can get
n
2
n_2
n2 sum
a
1
+
b
1
,
a
2
+
b
1
,
a
3
+
b
1
,
...
...
,
a
n
+
b
1
a_1+b_1,a_2+b_1,a_3+b_1,......,a_n+b_1
a1+b1,a2+b1,a3+b1,......,an+b1
a
1
+
b
2
,
a
2
+
b
2
,
a
3
+
b
2
,
...
...
,
a
n
+
b
2
a_1+b_2,a_2+b_2,a_3+b_2,......,a_n+b_2
a1+b2,a2+b2,a3+b2,......,an+b2
............................................................
a
1
+
b
n
,
a
2
+
b
n
,
a
3
+
b
n
,
...
...
,
a
n
+
b
n
a_1+b_n,a_2+b_n,a_3+b_n,......,a_n+b_n
a1+bn,a2+bn,a3+bn,......,an+bn
When a is ordered, the minimum value of each row (Group) is the first
So we want to find the sum of the minimum, then find the minimum in these n
Suppose found
a
1
+
b
2
a_1+b_2
a1 + b2 , then the array becomes
a
1
+
b
1
,
a
2
+
b
1
,
a
3
+
b
1
,
...
...
,
a
n
+
b
1
a_1+b_1,a_2+b_1,a_3+b_1,......,a_n+b_1
a1+b1,a2+b1,a3+b1,......,an+b1
a
2
+
b
2
,
a
3
+
b
2
,
...
...
,
a
n
+
b
2
a_2+b_2,a_3+b_2,......,a_n+b_2
a2+b2,a3+b2,......,an+b2
............................................................
a
1
+
b
n
,
a
2
+
b
n
,
a
3
+
b
n
,
...
...
,
a
n
+
b
n
a_1+b_n,a_2+b_n,a_3+b_n,......,a_n+b_n
a1+bn,a2+bn,a3+bn,......,an+bn
The minimum value of the second group becomes a 2 + b 2 a_2+b_2 a2 + b2 , then compare with other sums until the nth end is found, and repeat the process
m arrays are merged m-1 times to find the minimum sequence sum of the first n items
#include<iostream> #include <vector> #include <cmath> #include<cstring> #include<algorithm> #include <queue> #include<cstdio> #include<cstring> using namespace std; typedef pair<int, int> PII; const int N = 2400; int t,n,m; int a[N],b[N],k[N]; //Merge the two arrays to find the first n minimum values void merg() { //multiway merge //Each time the small top heap finds the smallest addition, and then the one behind + + is added to the heap priority_queue<PII,vector<PII>,greater<PII> > heap; for(int i=0;i<n;i++)heap.push({a[0]+b[i],0}); int c=0; while(c<n) { int f=heap.top().first; int s=heap.top().second; heap.pop(); k[c++]=f; heap.push({f-a[s]+a[s+1],s+1}); } for(int i=0;i<n;i++) a[i]=k[i]; } int main() { cin>>t; while(t--) { cin>>m>>n; for(int i=0;i<n;i++) cin>>a[i]; //Sort first //Ensure the order in the first group of each sequence at the beginning sort(a,a+n); m--; while (m -- ) { for(int i=0;i<n;i++) cin>>b[i]; merg(); } for(int i=0;i<n;i++) cout<<a[i]<<' '; cout<<endl; } return 0; }
1262 fish pond fishing
Title Link: Acwing 1262 fish pond fishing
Meaning: for n fish ponds, for each minute of fishing in the fish pond, the reduction x of fishing number in the next minute. Moving to adjacent fish ponds requires l grouping. Ask the maximum fishing value at T time
Analysis: for hidden multi-channel merging, you can't go back every time you go to a fish pond. In this way, it's better to fish this minute directly after passing through the fish pond. When the passing time is fixed, that is, when the time on the road is fixed, there is only fishing time left, and the maximum value is taken
The final idea is to enumerate the time on the road, fishing time, greedy for the most fish in the fish pond, and take max
#include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include <queue> using namespace std; typedef pair<int, int> PII; const int N = 110; int n,T; int a[N],t[N],l[N]; long long solve(int index,int time) { priority_queue<int,vector<int>> heap; for(int i=0;i<=index;i++) { int x=a[i]; while(x>0) { heap.push(x); x-=t[i]; } } long long sum=0; while(time>0&&heap.size()) { sum+=heap.top(); heap.pop(); time--; }//cout<<sum<<endl; return sum; } int main() { cin>>n; for(int i=0;i<n;i++)cin>>a[i]; for(int i=0;i<n;i++)cin>>t[i]; for(int i=1;i<=n-1;i++) { cin>>l[i]; l[i]+=l[i-1]; } cin>>T; long long sum=0; for(int i=0;i<=n-1;i++) sum=max(sum,solve(i,T-l[i])); cout<<sum<<endl; return 0; }
Matrix fast power
HDU1575Tr A
Title Link: HDU1575
Matrix fast power board subproblem
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> using namespace std; const int mod=9973; struct Eur{ int a[10][10]; }res; int T,n,k; Eur quick(Eur x,Eur y) { Eur t; memset(t.a,0,sizeof(t.a)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) t.a[i][j]=0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int p=0;p<n;p++) t.a[i][j]=(t.a[i][j]+x.a[i][p]*y.a[p][j])%mod; return t; } void quickE(int k) { Eur ans; memset(ans.a,0,sizeof(ans.a)); for(int i=0;i<n;i++)ans.a[i][i]=1; while(k) { if(k&1)ans=quick(ans,res); res=quick(res,res); k>>=1; } int sum=0; for(int i=0;i<n;i++)sum=(sum+ans.a[i][i])%mod; printf("%d\n",sum); } int main() { cin>>T; while(T--) { cin>>n>>k; for(int i=0;i<n;i++) for(int j=0;j<n;j++) {int x;cin>>x;res.a[i][j]=x%mod;} quickE(k); } return 0; }
POJ - 3233 Matrix Power Series
Title Link: POJ - 3233
Violence: Circular necessity TLE
Optimization: matrix fast power
matrix
E E S1 = Sk
o A A2 = A^k+1
matrix multiplication
Matrix multiplication of an nn
Multiplication of a 2nn matrix
Multiply a 2n*2n matrix
Three I wrote three broad to write simple points
At first, the multiplication matrix was written wrong, wa and n hair
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> using namespace std; typedef long long ll; struct mat{ ll a[120][121]; }res; ll n,mod,k; mat quick(mat x,mat y) { mat t; memset(t.a,0,sizeof(t.a)); for(int i=0;i<2*n;i++) for(int j=0;j<2*n;j++) for(int p=0;p<2*n;p++) t.a[i][j]=(t.a[i][j]+x.a[i][p]*y.a[p][j]%mod+mod)%mod; return t; } mat quickp(mat x,mat y) { mat t; memset(t.a,0,sizeof(t.a)); for(int i=0;i<2*n;i++) for(int j=0;j<n;j++) for(int p=0;p<2*n;p++) t.a[i][j]=(t.a[i][j]+x.a[i][p]*y.a[p][j]%mod)%mod; return t; } mat quick2(mat x,mat y) { mat t; memset(t.a,0,sizeof(t.a)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int p=0;p<n;p++) t.a[i][j]=(t.a[i][j]+x.a[i][p]*y.a[p][j]%mod+mod)%mod; return t; } mat quickm(mat x,ll k) { mat ans; memset(ans.a,0,sizeof(ans.a)); for(int i=0;i<2*n;i++)ans.a[i][i]=1; while(k) { if(k&1)ans=quick(ans,x); x=quick(x,x); k>>=1; } return ans; } int main() { cin>>n>>k>>mod; for(int i=0;i<n;i++) for(int j=0;j<n;j++) {ll x;cin>>x;res.a[i][j]=x%mod;} mat p,w; w=quick2(res,res); memset(p.a,0,sizeof(p.a)); for(int i=0;i<n;i++) p.a[i][i]=1; for(int i=0;i<n;i++) p.a[i][i+n]=1; for(int i=0;i<n;i++) for(int j=0;j<n;j++) p.a[i+n][j+n]=res.a[i][j]; p=quickm(p,k-1); for(int i=0;i<n;i++) for(int j=0;j<n;j++) res.a[i+n][j]=w.a[i][j]; mat r=quickp(p,res); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) if(j==0)printf("%lld",r.a[i][j]); else printf(" %lld",r.a[i][j]); printf("\n"); } return 0; }
Prime factor decomposition
HDU 6287 oral arithmetic training
Title Link: HDU 6287 oral arithmetic training
Analysis: this question looks at the data range, directly pass es violence, and then the product of each interval% d==0
It seems that the line segment tree will also tml
Final ac practice: decompose the quality factor
Use vector to record the index (subscript) of each prime number
Then decompose d with prime every time to see if there are so many prime numbers in l-r
#include<iostream> #include<math.h> #include<cstdio> #include<algorithm> using namespace std; const int N = 1e5+10; int t,n,m; int a[N]; vector<int>ve[N]; //Finding prime number by linear sieve method int primes[N], cnt; // Primes [] stores all primes bool st[N]; // st[x] is storage x screened out void get_primes(int n) { for (int i = 2; i <= n; i ++ ) { if (!st[i]) primes[cnt ++ ] = i; for (int j = 0; primes[j] <= n / i; j ++ ) { st[primes[j] * i] = true; if (i % primes[j] == 0) break; } } } //Decompose each number and add index to the list of prime factors void fen(int val,int index) { for(int i=0;st[val];i++) { while(val%primes[i]==0) { ve[primes[i]].push_back(index); val/=primes[i]; } } if(val>1)ve[val].push_back(index); } int main() { scanf("%d",&t); get_primes(N); while(t--) { scanf("%d%d",&n,&m); //Reset every initialization for(int i=0;i<cnt;i++) ve[primes[i]].clear(); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); fen(a[i],i); } while(m--) { int l,r,d; scanf("%d%d%d",&l,&r,&d); bool flag=true; for(int i=0;st[d];i++) { int num=0; while(d%primes[i]==0) { num++; d/=primes[i]; } if(num==0)continue; //Find the number of prime in the range of l and r and optimize it with lower bound int ll=lower_bound(ve[primes[i]].begin(),ve[primes[i]].end(),l)-ve[primes[i]].begin(); int rr=upper_bound(ve[primes[i]].begin(),ve[primes[i]].end(),r)-ve[primes[i]].begin(); //cout<<num<< ' '<<ll<<" "<<rr<<endl; if(rr-ll<num) { flag=false; break; } } //The final d is prime if(d!=1&&flag) { int ll=lower_bound(ve[d].begin(),ve[d].end(),l)-ve[d].begin(); int rr=upper_bound(ve[d].begin(),ve[d].end(),r)-ve[d].begin(); if(rr-ll<1) { flag=false; } } if(flag)puts("Yes"); else puts("No"); } } return 0; }