import java.util.*; import java.io.*; import java.text.*; public class Main{ //SOLUTION BEGIN void solve(int TC) throws Exception{ int n = ni(), q = ni(); long[] a = new long[n], b = new long[n]; for(int i = 0; i< n; i++)a[i] = nl(); for(int i = 0; i< n; i++)b[i] = nl(); int B = 200; int C = (n+B-1)/B; Block[] bucket = new Block[C];//Square root Decomposition for(int i = 0; i< C; i++){ bucket[i] = new Block(B); for(int j = i*B; j< Math.min(n, (i+1)*B); j++) bucket[i].add(new Line(b[j], a[j], j));//Adding lines with slope b[j] and constant a[j] to ith bucket bucket[i].build();//explained below } for(int qq = 0; qq{ long m, c; int pos; public Line(long M, long C, int ind){m = M;c = C;pos = ind;} long eval(long x){return m*x+c;} public int compareTo(Line l){ //Sorting blocks in increasing order of slopes if(m!=l.m)return Long.compare(m, l.m); return Long.compare(c, l.c);//If slopes equal, sorted in order of coefficients. } } //Calculates intersection point of two lines, rounded to the next integet value. long intersection(Line l1, Line l2){ if(l1.m==l2.m && l1.c=l2.c)return 0;//because these lines will never intersect, according to our sorting long a = l2.c-l1.c, b = l1.m-l2.m; return (a+b-1)/b;//Rounded up } class Block{ //q_cnt - Number of times B was added to A after last updateBlock. cur_max - our index of the line having maximum value at value q_cnt. int q_cnt, cur_max; //coefAdd - Sum of all increments by query type 4 to array A, since last update //slopeAdd - Sum of all increments by query of type 3 to array B, since last update //slopeEffect, Sum of combined effect of type 2 operation on array A, since last update. long coefAdd, slopeAdd, slopeEffect; int lsize = 0, hsize = 0, isize = 0;//Sizes of following arrays Line[] lines, hull; // ArrayList lines, hull; long[] intersections; // ArrayList intersections; public Block(int SIZE){ lines = new Line[SIZE];hull = new Line[SIZE]; intersections = new long[SIZE]; // lines = new ArrayList<>();hull = new ArrayList<>(); // intersections = new ArrayList<>(); q_cnt = cur_max = 0; coefAdd = slopeAdd = slopeEffect = 0; } //Adds line to block, used during preprocessing only void add(Line l){lines[lsize++] = l;} //Initialisation function, Sort the lines for hull and create initial convex hull void build(){ Arrays.sort(lines, 0, lsize); convexhull(); } //Build can be used, but will add a factor of log(blocksize) to complexity. //This is called, when slopes of segment [l,r] are increased by X.ie Increment on B is done on [l,r]. It preserves the sorting order of lines, required for Convex hull. //Since Hull is required to be rebuilt after this sorting, it is always called whenever updateBlockBySlope is called. void updateBlockBySlope(int l, int r){ ArrayList v1 = new ArrayList<>(), v2 = new ArrayList<>(); for(int i = 0; i< lsize; i++){ if(lines[i].pos>=l && lines[i].pos<=r)v1.add(lines[i]); else v2.add(lines[i]); } int b = lsize; lsize = 0; for(int i1 = 0, i2 = 0; i1+i2v2.get(i2).m || (v1.get(i1)==v2.get(i2) && v1.get(i1).c>v2.get(i2).c))f = false; if(f)lines[lsize++] = v1.get(i1++); else lines[lsize++] = v2.get(i2++); } } } //Updates the lines in whole block void updateBlock(){ for(int i = 0; i< lsize; i++){ lines[i].c += coefAdd + lines[i].m*q_cnt+slopeEffect;//Added effect of b[i]* number of times operation 2 performed //plus added combined effect of operation 3 for every increare in array B before every operation 2 since last update lines[i].m+=slopeAdd;//Simply added effect of type 3 operation to slope } //Resetting q_cnt = 0; coefAdd = 0;slopeAdd = 0;slopeEffect = 0; } //Makes convex hull from lines. Simple variant convex hull is used as lines have slopes sorted. //Refer Wiki page mentioned in editorial for details. void convexhull(){ isize = 0;hsize = 0; cur_max = 0;//Current best pointer is reset, since hull is being rebuild. for(int i = 0; i< lsize; i++){ while(hsize>=2 && intersection(lines[i], hull[hsize-1]) <= intersections[isize-1]){ hsize--; isize--; } boolean add = true; if(hsize>0) if(intersection(lines[i], hull[hsize-1])>IINF) add = false; if(add){ if(hsize>0) intersections[isize++] = intersection(lines[i], hull[hsize-1]); hull[hsize++] = lines[i]; } } } //Range l to r has been modified. O(B) complexity. //If slopes are changed, UpdateBlockBySlope is needed. //else just rebuilding convex hull is sufficient void update(int l, int r, boolean reorder){ if(reorder)updateBlockBySlope(l,r);//Ensures sorted order of lines, for convex hull convexhull();//Rebuilding convex hull } //Returns maximum value in block long getMax(){ //If only one line is always max in whole block. if(isize == 0)return hull[0].eval(q_cnt)+coefAdd+slopeEffect; //Moving our current pointer to best line, the line having maximum value at q_cnt while(cur_max=intersections[cur_max]) cur_max++; return hull[cur_max].eval(q_cnt)+coefAdd+slopeEffect; } //Returns max in range long getMax(int l, int r){ long ans = -IINF; for(int i = 0; i< lsize; i++) if(lines[i].pos>=l && lines[i].pos<=r) ans = Math.max(ans, lines[i].eval(q_cnt)+coefAdd+slopeEffect); return ans; } void incrementAB(){ //The array B is added to array A, so increased query point by 1. //So, suppose q_cnt was 0. For any line, query(0) would return line.c which is a[i]. //Now, after increasing q_cnt by 1, we make call to query(1), which returns m+c, ie b[i]+a[i], Thus, performing 2nd operation on whole block. q_cnt++; //The increase in B made since last update, will be added to A, //So, we add the increase in B to slopeEffect slopeEffect+=slopeAdd; } //Manual 2nd operation in range [l,r] void incrementAB(int l, int r){ updateBlock();//All lines are updated for(int i = 0; i< lsize; i++) if(lines[i].pos>=l && lines[i].pos<=r) lines[i].c+=lines[i].m; update(l, r, false);//Convex hull is required to be built again after change. } //Operation 4 on whole block. void incrementA(long val){ coefAdd+=val; } //OPeration 4 in range [l,r] void incrementA(int l, int r, long val){ updateBlock(); for(int i = 0; i< lsize; i++) if(lines[i].pos>=l && lines[i].pos<=r) lines[i].c+=val; update(l,r,false); } //Operation 3 on whole block void incrementB(long val){ slopeAdd+=val; } //Operation 3 in range[l,r] void incrementB(int l, int r, long val){ updateBlock(); for(int i = 0; i< lsize; i++) if(lines[i].pos>=l && lines[i].pos<=r) lines[i].m+=val; update(l,r,true); } } //SOLUTION ENDS long gcd(long a, long b){return (b==0)?a:gcd(b,a%b);} int gcd(int a, int b){return (b==0)?a:gcd(b,a%b);} int bit(long n){return (n==0)?0:(1+bit(n&(n-1)));} void p(Object o){out.print(o);} void pn(Object o){out.println(o);} void pni(Object o){out.println(o);out.flush();} String n(){return in.next();} String nln(){return in.nextLine();} int ni(){return Integer.parseInt(in.next());} long nl(){return Long.parseLong(in.next());} double nd(){return Double.parseDouble(in.next());} class FastReader{ BufferedReader br; StringTokenizer st; public FastReader(){ br = new BufferedReader(new InputStreamReader(System.in)); } public FastReader(String s) throws Exception{ br = new BufferedReader(new FileReader(s)); } String next(){ while (st == null || !st.hasMoreElements()){ try{ st = new StringTokenizer(br.readLine()); }catch (IOException e){ e.printStackTrace(); } } return st.nextToken(); } String nextLine(){ String str = ""; try{ str = br.readLine(); }catch (IOException e){ e.printStackTrace(); } return str; } } long mod = (int)1e9+7, IINF = (long)1e18; final int MAX = (int)1e4+1, INF = (int)1e9, root = 3; DecimalFormat df = new DecimalFormat("0.00000000"); double PI = 3.141592653589793238462643383279502884197169399375105820974944; static boolean multipleTC = false, memory = true; FastReader in;PrintWriter out; public static void main(String[] args) throws Exception{ if(memory)new Thread(null, new Runnable() {public void run(){try{new Main().run();}catch(Exception e){e.printStackTrace();}}}, "1", 1 << 28).start(); else new Main().run(); } void run() throws Exception{ in = new FastReader(); out = new PrintWriter(System.out); for(int i = 1, T= (multipleTC)?ni():1; i<= T; i++)solve(i); out.flush(); out.close(); } }