#include #include #include #include #define REP(i,a,b) for(i=a;i treeRight[node]) B = treeRight[node]; if(A == treeLeft[node] && B == treeRight[node]){ *sum = treeSum[node]; *LT = treeLT[node]; *RT = treeRT[node]; return; } treeRecalc(node); if(B <= treeRight[n1]){ treeGetSum(A, B, sum, LT, RT, n1); return; } if(treeLeft[n2] <= A){ treeGetSum(A, B, sum, LT, RT, n2); return; } treeGetSum(A, B, &sum1, <1, &RT1, n1); treeGetSum(A, B, &sum2, <2, &RT2, n2); if(sum1==-1 || sum2==-1){ *sum = -1; return; } *sum = sum1 + sum2; *LT = LT1; *RT = RT2; if(LT2 != RT1) *sum += U[towerT[LT2]][towerT[RT1]]; } void treeSetTower(int A, int B, int t, int node){ int n1 = node * 2 + 1, n2 = node * 2 + 2; int sz = treeRight[node] - treeLeft[node]; ll sum1, sum2; int LT1, LT2, RT1, RT2; if(A < treeLeft[node]) A = treeLeft[node]; if(B > treeRight[node]) B = treeRight[node]; if(A >= B) return; if(A == treeLeft[node] && B == treeRight[node]){ treeFixed[node] = 1; treeSum[node] = 2 * towerC[t] * ((sumX[B] - sumX[A]) - (ll)towerY[t] * sz); if(treeSum[node] < 0) treeSum[node] *= -1; treeLT[node] = treeRT[node] = t; return; } treeRecalc(node); treeSetTower(A, B, t, n1); treeSetTower(A, B, t, n2); sum1 = treeSum[n1]; sum2 = treeSum[n2]; LT1 = treeLT[n1]; LT2 = treeLT[n2]; RT1 = treeRT[n1]; RT2 = treeRT[n2]; if(sum1==-1 || sum2==-1){ treeSum[node] = -1; return; } treeSum[node] = sum1 + sum2; treeLT[node] = LT1; treeRT[node] = RT2; if(LT2 != RT1) treeSum[node] += U[towerT[LT2]][towerT[RT1]]; } int main(){ int i,j,k,l; int A, B, Y, R, C, T, t; int t1, t2; int mode; ll res; int LT, RT; scanf("%d%d%d",&N,&M,&Q); rep(i,N) scanf("%d",X+i); rep(i,M) rep(j,M) scanf("%d",U[i]+j); sumX[0] = 0; rep(i,N) sumX[i+1] = sumX[i] + X[i]; towerSize = 0; dataSize = 1; while(dataSize < N) dataSize *= 2; treeNode = dataSize * 2 - 1; rep(i,treeNode) treeFixed[i] = 0, treeSum[i] = treeLT[i] = treeRT[i] = -1; treeLeft[0] = 0, treeRight[0] = dataSize; rep(i,treeNode/2){ int n1 = i * 2 + 1, n2 = i * 2 + 2; int sz = treeRight[i] - treeLeft[i]; treeLeft[n1] = treeLeft[i]; treeRight[n1] = treeLeft[i] + sz / 2; treeLeft[n2] = treeLeft[i] + sz / 2; treeRight[n2] = treeRight[i]; } while(Q--){ scanf("%d",&mode); if(mode == 1){ scanf("%d%d",&A,&B); A--; B--; treeGetSum(A, B+1, &res, <, &RT, 0); if(res < 0){ puts("impossible"); } else { res -= ab(X[A] - towerY[LT]) * towerC[LT]; res -= ab(X[B] - towerY[RT]) * towerC[RT]; printf("%lld\n",res); } } else { scanf("%d%d%d%d",&Y,&R,&C,&T); T--; t = towerSize++; towerY[t] = Y; towerR[t] = R; towerC[t] = C; towerT[t] = T; A = intArrayBinarySearchSmallElement(X, N, Y - R) + 1; B = intArrayBinarySearchSmallElement(X, N, Y + 1); if(A <= B) treeSetTower(A, B+1, t, 0); A = intArrayBinarySearchSmallElement(X, N, Y + 1) + 1; B = intArrayBinarySearchSmallElement(X, N, Y + R + 1); if(A <= B) treeSetTower(A, B+1, t, 0); } } return 0; }