uva 11992 - Fast Matrix Operations
简单的线段树的题;
有两种方法写这个题,目前用的熟是这种慢点的;
不过不知道怎么老是T;
感觉网上A过的人的时间度都好小,但他们都是用数组实现的
难道是指针比数组慢?
好吧,以后多用数组写写吧!
超时的代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define maxn 1000009 5 using namespace std; 6 7 struct node 8 { 9 int l,r; 10 int ma,mi,sum; 11 int ad,st; 12 bool flag1,flag2; 13 node *left,*right; 14 } no[maxn*3]; 15 int nonocount; 16 17 void build(node *rt,int l,int r) 18 { 19 rt->l=l; 20 rt->r=r; 21 rt->sum=0; 22 rt->ma=0; 23 rt->mi=0; 24 if(l==r) 25 return; 26 int mid=(l+r)>>1; 27 rt->left=no+nonocount++; 28 rt->right=no+nonocount++; 29 build(rt->left,l,mid); 30 build(rt->right,mid+1,r); 31 } 32 33 void maintain(node *rt) 34 { 35 rt->ma=max(rt->left->ma,rt->right->ma); 36 rt->mi=min(rt->left->mi,rt->right->mi); 37 rt->sum=rt->left->sum+rt->right->sum; 38 } 39 40 void pushdown(node *rt) 41 { 42 if(rt->flag1==1) 43 { 44 rt->flag1=0; 45 rt->ma+=rt->ad; 46 rt->mi+=rt->ad; 47 rt->sum+=(rt->r-rt->l+1)*rt->ad; 48 if(rt->l!=rt->r) 49 { 50 rt->left->ad=rt->right->ad=rt->ad; 51 rt->left->flag1=rt->right->flag1=1; 52 pushdown(rt->left); 53 pushdown(rt->right); 54 } 55 rt->ad=0; 56 return; 57 } 58 if(rt->flag2==1) 59 { 60 rt->flag2=0; 61 rt->sum=(rt->r-rt->l+1)*rt->ad; 62 rt->ma=rt->mi=rt->ad; 63 if(rt->l!=rt->r) 64 { 65 rt->left->ad=rt->right->ad=rt->ad; 66 rt->left->flag2=rt->right->flag2=1; 67 pushdown(rt->left); 68 pushdown(rt->right); 69 } 70 rt->ad=0; 71 return; 72 } 73 } 74 75 void add(node *rt,int l,int r,int v) 76 { 77 if(l==rt->l&&r==rt->r) 78 { 79 rt->ad=v; 80 rt->flag1=1; 81 pushdown(rt); 82 return; 83 } 84 int mid=(rt->l+rt->r)>>1; 85 if(r<=mid)add(rt->left,l,r,v); 86 else if(l>=mid+1)add(rt->right,l,r,v); 87 else 88 { 89 add(rt->left,l,mid,v); 90 add(rt->right,mid+1,r,v); 91 } 92 maintain(rt); 93 } 94 95 void set(node *rt,int l,int r,int v) 96 { 97 if(l==rt->l&&r==rt->r) 98 { 99 rt->ad=v; 100 rt->flag2=1; 101 pushdown(rt); 102 return; 103 } 104 int mid=(rt->l+rt->r)>>1; 105 if(r<=mid)set(rt->left,l,r,v); 106 else if(l>=mid+1)set(rt->right,l,r,v); 107 else 108 { 109 set(rt->left,l,mid,v); 110 set(rt->right,mid+1,r,v); 111 } 112 maintain(rt); 113 } 114 int ssum,mma,mmi; 115 void query(node *rt,int l,int r) 116 { 117 if(l==rt->l&&r==rt->r) 118 { 119 ssum+=rt->sum; 120 mma=max(rt->ma,mma); 121 mmi=min(rt->mi,mmi); 122 return; 123 } 124 int mid=(rt->l+rt->r)>>1; 125 if(r<=mid)query(rt->left,l,r); 126 else if(l>=mid+1)query(rt->right,l,r); 127 else 128 { 129 query(rt->left,l,mid); 130 query(rt->right,mid+1,r); 131 } 132 } 133 134 int main() 135 { 136 int n,m,q,cmd,x1,y1,x2,y2,v; 137 while(scanf("%d%d%d",&n,&m,&q)!=EOF) 138 { 139 nonocount=22; 140 for(int i=1; i<=n; i++) 141 build(no+i,1,m); 142 while(q--) 143 { 144 scanf("%d",&cmd); 145 if(cmd==1) 146 { 147 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 148 scanf("%d",&v); 149 for(int i=x1; i<=x2; i++) 150 add(no+i,y1,y2,v); 151 } 152 else if(cmd==2) 153 { 154 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 155 scanf("%d",&v); 156 for(int i=x1; i<=x2; i++) 157 set(no+i,y1,y2,v); 158 } 159 else 160 { 161 int ans=0; 162 mma=-999999,mmi=6666666; 163 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 164 for(int i=x1; i<=x2; i++) 165 { 166 ssum=0; 167 query(no+i,y1,y2); 168 ans+=ssum; 169 } 170 printf("%d %d %d\n",ans,mmi,mma); 171 } 172 } 173 } 174 return 0; 175 }