The main topic: given n operations, each operation has four forms, after operation if <l becomes l,>r to become R, now given Q input, beg their output
n,q<=10w
Set the number of Q to a segment tree, four operations can be done on the line tree
But what about overflow?
Easy to find if x<=y, then x must <=y after operation
Because four operations are linear, the overflow does not reverse the size relationship of two numbers
So we can sort the number of Q ahead of time so the overflow must be two consecutive intervals.
As for how to find the end overflow interval ... Each node maintains a range of maximum and minimum values just fine.
In addition, the data is still relatively conscience does not appear explode long long this kind of p matter rest assured write it
That's a simple way of thinking. I've written a whole four-time code--I'm going to have to figure it out before I write the code--at least the TM-initiator simulation sample. Qaq
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include < Algorithm> #define M 100100using namespace Std;int n,m,l,r;int q[m];long long a[m];struct operation{int type,x;friend i stream& operator >> (IStream &_,operation &o) {char p[10];scanf ("%s%d", p,&o.x); switch (p[0]) { Case ' + ': o.type=1;break;case '-': o.type=2;break;case ' * ': O.type=3;break;case ' @ ': o.type=4;break;} return _;}} Operations[m];struct segtree{segtree *ls,*rs;long long Times_mark,k,b;long long min_num,max_num; Segtree (): LS (0x0), RS (0x0), Times_mark (1), K (0), B (0) {}void build_tree (int x,int y) {int mid=x+y>>1;min_num=a[x]; Max_num=a[y];if (x==y) return;(ls=new segtree)->build_tree (x,mid);(rs=new segtree)->build_tree (mid+1,y);} void Get_mark (int x,int y,long long _,long long __,long long ___) {min_num=_*min_num+__*a[x]+___;max_num=_*max_num+__*a[ y]+___;times_mark*=_;k*=_;b*=_;k+=__;b+=___;} void Push_down (int x,int y) {int Mid=x+y>>1;ls->get_mark (X,MID,TIMES_MARK,K,B); Rs->get_mark (mid+1,y,times_mark,k,b); times_mark=1;k=b=0;} int Get_ans (int x,int y,int pos) {int mid=x+y>>1;if (x==y) return max_num; Push_down (x, y), if (Pos<=mid) return Ls->get_ans (X,mid,pos); Elsereturn Rs->get_ans (Mid+1,y,pos);} void get_l (int x,int y) {int mid=x+y>>1;if (x==y) {Get_mark (x,y,0,0,l); return;} Push_down (x, y), if (rs->min_num<l) Ls->get_mark (x,mid,0,0,l), rs->get_l (Mid+1,y), elsels->get_l (×, mid); min_num=ls->min_num;max_num=rs->max_num;} void Get_r (int x,int y) {int mid=x+y>>1;if (x==y) {Get_mark (x,y,0,0,r); return;} Push_down (x, y), if (ls->max_num>r) Rs->get_mark (mid+1,y,0,0,r), Ls->get_r (X,mid); Elsers->get_r (mid+ 1,y); min_num=ls->min_num;max_num=rs->max_num;}} *tree=new Segtree;int Main () {int i;cin>>n>>l>>r;for (i=1;i<=n;i++) cin>>operations[i]; Cin>>m;for (i=1;i<=m;i++) scanf ("%d", &q[i]), A[i]=q[i];sort (a+1,a+m+1); Tree->build_tree (1,m); for ( i=1;i<=n;i++) {switch (opeRations[i].type) {case 1:tree->get_mark (1,m,1,0,operations[i].x); Break;case 2:tree->get_mark (1,m,1,0,- operations[i].x); break;case 3:tree->get_mark (1,m,operations[i].x,0,0); Break;case 4:tree->Get_Mark (1,m,1, operations[i].x,0); break;} if (tree->min_num<l) tree->get_l (1,m), if (tree->max_num>r) Tree->get_r (1,m);} for (i=1;i<=m;i++) {int pos=lower_bound (a+1,a+m+1,q[i])-a;printf ("%d\n", Tree->get_ans (1,m,pos));} return 0;}
Bzoj 3878 Ahoi2014 Strange Calculator line-segment tree