#include <iostream> #include <vector> #include <algorithm> using namespace std; typedef long long ll; const ll MOD = 1000000007; struct Layer{ ll distA, distB; ll size; }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n,q; cin >> n >> q; vector<ll>A(n); for(int i=1;i<n;i++) cin >> A[i]; while(q--){ int Wa,Wb,Wlca; cin >> Wa >> Wb >> Wlca; vector<Layer>L; auto build_layers = [&](ll distA, ll distB, int rootLayer, bool addRoot, int firstSkip){ ll size = 1; if(addRoot) L.push_back(Layer{distA, distB, size}); for(int l=rootLayer;l<n;l++){ size = (size*(A[l]-firstSkip))%MOD; distA++; distB++; firstSkip = 0; L.push_back(Layer{distA, distB, size}); } }; //build layers above LCA for(int layer=Wlca-1;layer>0;layer--) build_layers(Wa-layer, Wb-layer, layer, true, 1); //build layers from LCA if(Wa!=Wlca && Wb!=Wlca) build_layers(Wa-Wlca, Wb-Wlca, Wlca, true, 2); else if(Wa!=Wlca || Wb!=Wlca) build_layers(Wa-Wlca, Wb-Wlca, Wlca, true, 1); else build_layers(0, 0, Wlca, true, 0); //build layers between for(int l=Wlca+1;l<Wa;l++) build_layers(Wa-l, l+Wb-2*Wlca, l, true, 1); for(int l=Wlca+1;l<Wb;l++) build_layers(l+Wa-2*Wlca, Wb-l, l, true, 1); //build layers from A,B if(Wa!=Wlca) build_layers(0, Wa+Wb-2*Wlca, Wa, true, 0); if(Wb!=Wlca) build_layers(Wa+Wb-2*Wlca, 0, Wb, true, 0); //process layers sort(L.begin(), L.end(), [](const Layer& l1, const Layer& l2){ return l1.distA+l1.distB > l2.distA+l2.distB; }); ll result = 0; bool half=false; for(Layer l : L){ if(half){ result += l.distA*(l.size/2); result -= l.distB*((l.size+1)/2); if(l.size%2==1) half=false; } else{ result += l.distA*((l.size+1)/2); result -= l.distB*(l.size/2); if(l.size%2==1) half=true; } result %= MOD; } cout << (result+MOD)%MOD << "\n"; } 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 | #include <iostream> #include <vector> #include <algorithm> using namespace std; typedef long long ll; const ll MOD = 1000000007; struct Layer{ ll distA, distB; ll size; }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n,q; cin >> n >> q; vector<ll>A(n); for(int i=1;i<n;i++) cin >> A[i]; while(q--){ int Wa,Wb,Wlca; cin >> Wa >> Wb >> Wlca; vector<Layer>L; auto build_layers = [&](ll distA, ll distB, int rootLayer, bool addRoot, int firstSkip){ ll size = 1; if(addRoot) L.push_back(Layer{distA, distB, size}); for(int l=rootLayer;l<n;l++){ size = (size*(A[l]-firstSkip))%MOD; distA++; distB++; firstSkip = 0; L.push_back(Layer{distA, distB, size}); } }; //build layers above LCA for(int layer=Wlca-1;layer>0;layer--) build_layers(Wa-layer, Wb-layer, layer, true, 1); //build layers from LCA if(Wa!=Wlca && Wb!=Wlca) build_layers(Wa-Wlca, Wb-Wlca, Wlca, true, 2); else if(Wa!=Wlca || Wb!=Wlca) build_layers(Wa-Wlca, Wb-Wlca, Wlca, true, 1); else build_layers(0, 0, Wlca, true, 0); //build layers between for(int l=Wlca+1;l<Wa;l++) build_layers(Wa-l, l+Wb-2*Wlca, l, true, 1); for(int l=Wlca+1;l<Wb;l++) build_layers(l+Wa-2*Wlca, Wb-l, l, true, 1); //build layers from A,B if(Wa!=Wlca) build_layers(0, Wa+Wb-2*Wlca, Wa, true, 0); if(Wb!=Wlca) build_layers(Wa+Wb-2*Wlca, 0, Wb, true, 0); //process layers sort(L.begin(), L.end(), [](const Layer& l1, const Layer& l2){ return l1.distA+l1.distB > l2.distA+l2.distB; }); ll result = 0; bool half=false; for(Layer l : L){ if(half){ result += l.distA*(l.size/2); result -= l.distB*((l.size+1)/2); if(l.size%2==1) half=false; } else{ result += l.distA*((l.size+1)/2); result -= l.distB*(l.size/2); if(l.size%2==1) half=true; } result %= MOD; } cout << (result+MOD)%MOD << "\n"; } return 0; } |