#include <iostream>
#include <string>
#include <algorithm>
#include "message.h"
using namespace std;
int n, m;
string a, b;
int lZmian1[100002], lZmian2[100002], lSzokow1[100002], lSzokow2[100002];//[n][m]
int *lZmianTer=lZmian1, *lZmianPoprz=lZmian2, *lSzokowTer=lSzokow1, *lSzokowPoprz=lSzokow2;
void licz(int doIlu)
{
for (int j=0; j<=m; ++j)
lZmianTer[j]=j;
for (int i=1; i<=doIlu; ++i)
{
if ((i&1023)==0)
cerr<<i<<endl;
swap(lZmianTer, lZmianPoprz);
swap(lSzokowTer, lSzokowPoprz);
lZmianTer[0]=i;
for (int j=1; j<=m; ++j)
{
int ll=lZmianPoprz[j-1]+(a[i-1]==b[j-1] ? 0 : 1);
int lz=min(lZmianTer[j-1]+1, min(lZmianPoprz[j]+1, ll));
lZmianTer[j]=lz;
int lsz=1000000;
if (lz==lZmianTer[j-1]+1)
lsz=lSzokowTer[j-1];
if (lz==lZmianPoprz[j]+1)
lsz=min(lsz, lSzokowPoprz[j]);
if (lz==ll)
lsz=min(lsz, lSzokowPoprz[j-1]+(a[i-1]<b[j-1] ? 1 : 0));
lSzokowTer[j]=lsz;
}
}
}
int qlZmian1[100002], qlZmian2[100002], qlSzokow1[100002], qlSzokow2[100002];//[n][m]
int *qlZmianTer=qlZmian1, *qlZmianPoprz=qlZmian2, *qlSzokowTer=qlSzokow1, *qlSzokowPoprz=qlSzokow2;
void qlicz(int doIlu)
{
for (int j=0; j<=m; ++j)
qlZmianTer[j]=j;
for (int i=1; i<=doIlu; ++i)
{
if ((i&1023)==0)
cerr<<i<<endl;
swap(qlZmianTer, qlZmianPoprz);
swap(qlSzokowTer, qlSzokowPoprz);
qlZmianTer[0]=i;
for (int j=1; j<=m; ++j)
{
int ll=qlZmianPoprz[j-1]+(a[i-1]==b[j-1] ? 0 : 1);
int lz=min(qlZmianTer[j-1]+1, min(qlZmianPoprz[j]+1, ll));
qlZmianTer[j]=lz;
int lsz=1000000;
if (lz==qlZmianTer[j-1]+1)
lsz=qlSzokowTer[j-1];
if (lz==qlZmianPoprz[j]+1)
lsz=min(lsz, qlSzokowPoprz[j]);
if (lz==ll)
lsz=min(lsz, qlSzokowPoprz[j-1]+(a[i-1]<b[j-1] ? 1 : 0));
qlSzokowTer[j]=lsz;
}
}
}
int main()
{
if (MyNodeId()>1)
return 0;
ios_base::sync_with_stdio(false);
cin>>n>>m>>a>>b;
if (n*(long long)m<=10000000 || NumberOfNodes()==1)
{
if (MyNodeId())
return 0;
licz(n);
cout<<lZmianTer[m]<<' '<<lSzokowTer[m]<<endl;
return 0;
}
int srodek=(n+16)/2;
if (MyNodeId())
{
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
qlicz(n-srodek);
for (int j=0; j<=m; ++j)
{
PutInt(0, qlZmianTer[j]);
PutInt(0, qlSzokowTer[j]);
}
Send(0);
return 0;
}
licz(srodek);
Receive(1);
for (int j=0; j<=m; ++j)
{
qlZmianTer[j]=GetInt(1);
qlSzokowTer[j]=GetInt(1);
}
int najL=1000000, najSz=1000000;
for (int j=0; j<=m; ++j)
{
int l=lZmianTer[j]+qlZmianTer[m-j], s=lSzokowTer[j]+qlSzokowTer[m-j];
if (l<najL || (l==najL && s<najSz))
{
najL=l;
najSz=s;
}
}
cout<<najL<<' '<<najSz<<endl;
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #include <iostream> #include <string> #include <algorithm> #include "message.h" using namespace std; int n, m; string a, b; int lZmian1[100002], lZmian2[100002], lSzokow1[100002], lSzokow2[100002];//[n][m] int *lZmianTer=lZmian1, *lZmianPoprz=lZmian2, *lSzokowTer=lSzokow1, *lSzokowPoprz=lSzokow2; void licz(int doIlu) { for (int j=0; j<=m; ++j) lZmianTer[j]=j; for (int i=1; i<=doIlu; ++i) { if ((i&1023)==0) cerr<<i<<endl; swap(lZmianTer, lZmianPoprz); swap(lSzokowTer, lSzokowPoprz); lZmianTer[0]=i; for (int j=1; j<=m; ++j) { int ll=lZmianPoprz[j-1]+(a[i-1]==b[j-1] ? 0 : 1); int lz=min(lZmianTer[j-1]+1, min(lZmianPoprz[j]+1, ll)); lZmianTer[j]=lz; int lsz=1000000; if (lz==lZmianTer[j-1]+1) lsz=lSzokowTer[j-1]; if (lz==lZmianPoprz[j]+1) lsz=min(lsz, lSzokowPoprz[j]); if (lz==ll) lsz=min(lsz, lSzokowPoprz[j-1]+(a[i-1]<b[j-1] ? 1 : 0)); lSzokowTer[j]=lsz; } } } int qlZmian1[100002], qlZmian2[100002], qlSzokow1[100002], qlSzokow2[100002];//[n][m] int *qlZmianTer=qlZmian1, *qlZmianPoprz=qlZmian2, *qlSzokowTer=qlSzokow1, *qlSzokowPoprz=qlSzokow2; void qlicz(int doIlu) { for (int j=0; j<=m; ++j) qlZmianTer[j]=j; for (int i=1; i<=doIlu; ++i) { if ((i&1023)==0) cerr<<i<<endl; swap(qlZmianTer, qlZmianPoprz); swap(qlSzokowTer, qlSzokowPoprz); qlZmianTer[0]=i; for (int j=1; j<=m; ++j) { int ll=qlZmianPoprz[j-1]+(a[i-1]==b[j-1] ? 0 : 1); int lz=min(qlZmianTer[j-1]+1, min(qlZmianPoprz[j]+1, ll)); qlZmianTer[j]=lz; int lsz=1000000; if (lz==qlZmianTer[j-1]+1) lsz=qlSzokowTer[j-1]; if (lz==qlZmianPoprz[j]+1) lsz=min(lsz, qlSzokowPoprz[j]); if (lz==ll) lsz=min(lsz, qlSzokowPoprz[j-1]+(a[i-1]<b[j-1] ? 1 : 0)); qlSzokowTer[j]=lsz; } } } int main() { if (MyNodeId()>1) return 0; ios_base::sync_with_stdio(false); cin>>n>>m>>a>>b; if (n*(long long)m<=10000000 || NumberOfNodes()==1) { if (MyNodeId()) return 0; licz(n); cout<<lZmianTer[m]<<' '<<lSzokowTer[m]<<endl; return 0; } int srodek=(n+16)/2; if (MyNodeId()) { reverse(a.begin(), a.end()); reverse(b.begin(), b.end()); qlicz(n-srodek); for (int j=0; j<=m; ++j) { PutInt(0, qlZmianTer[j]); PutInt(0, qlSzokowTer[j]); } Send(0); return 0; } licz(srodek); Receive(1); for (int j=0; j<=m; ++j) { qlZmianTer[j]=GetInt(1); qlSzokowTer[j]=GetInt(1); } int najL=1000000, najSz=1000000; for (int j=0; j<=m; ++j) { int l=lZmianTer[j]+qlZmianTer[m-j], s=lSzokowTer[j]+qlSzokowTer[m-j]; if (l<najL || (l==najL && s<najSz)) { najL=l; najSz=s; } } cout<<najL<<' '<<najSz<<endl; return 0; } |
English