洛谷P4390 Mokia CDQ分治
喜闻乐见的CDQ分治被我搞的又WA又T.....
大致思路是这样的:把询问用二维前缀和的思想拆成4个子询问。然后施CDQ大法即可。
我却灵光一闪:树状数组是可以求区间和的,那么我们只拆成两个子询问不就行了?在统计的时候统计一个差值即可。
然后一交,自信40...
那么果然还是拆成4个吧...T了,60分。
然后放弃那个朴素的sort版CDQ,采用了归并,就A了。
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 const int N = 500010,M = 3000010; 5 inline int read() 6 { 7 int ans=0;char ch=getchar(); 8 while(ch<'0'||ch>'9') ch=getchar(); 9 while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar(); 10 return ans; 11 } 12 struct Node 13 { 14 int x,y,k,type,t; 15 }node[N],temp[N];int tot; 16 int ask[10010],cnt,n; 17 inline bool cmp_x(Node a,Node b) 18 { 19 if(a.x!=b.x)return a.x<b.x; 20 return a.type<b.type; 21 } 22 inline bool cmp_t(Node a,Node b) 23 { 24 if(a.t!=b.t)return a.t<b.t; 25 return a.type<b.type; 26 } 27 int ta[M]; 28 inline int lowbit(int i) {return i&(-i);} 29 inline void add(int x,int a) 30 { 31 if(x<=0) return; 32 for(int i=x;i<=n;i+=lowbit(i)) ta[i]+=a; 33 return; 34 } 35 inline int getsum(int x) 36 { 37 if(x<=0) return 0; int ans=0; 38 for(int i=x;i>0;i-=lowbit(i)) ans+=ta[i]; 39 return ans; 40 } 41 void CDQ(int l,int r) 42 { 43 if(l==r)return; 44 int mid=(l+r)>>1; 45 CDQ(l,mid);CDQ(mid+1,r); 46 47 int i=l,j=mid+1,t=0; 48 while(j<=r||i<=mid) 49 { 50 if(j>r||(i<=mid&&node[i].x<=node[j].x)) 51 { 52 if(node[i].type==1) add(node[i].y,node[i].k); 53 temp[++t]=node[i++]; 54 } 55 else 56 { 57 if(node[j].type>1) node[j].k+=getsum(node[j].y); 58 temp[++t]=node[j++]; 59 } 60 } 61 for(j=l;j<i;j++) 62 { 63 if(node[j].type==1)add(node[j].y,-node[j].k); 64 } 65 t=0; 66 for(i=l;i<=r;i++) node[i]=temp[++t]; 67 return; 68 } 69 int main() 70 { 71 n=read();n=read(); 72 int flag,x,y,xx,yy,k,time=0; 73 flag=read(); 74 while(flag!=3) 75 { 76 time++; 77 if(flag==1) 78 { 79 x=read();y=read();k=read(); 80 node[++tot].x=x; 81 node[tot].y=y; 82 node[tot].k=k; 83 node[tot].t=time; 84 node[tot].type=1; 85 } 86 else 87 { 88 x=read();y=read();xx=read();yy=read(); 89 x--;y--; 90 node[++tot].x=xx; 91 node[tot].y=yy; 92 node[tot].t=time; 93 node[tot].type=2; 94 ask[++cnt]=tot; 95 node[++tot].x=x; 96 node[tot].y=y; 97 node[tot].t=time; 98 node[tot].type=3; 99 node[++tot].x=x; 100 node[tot].y=yy; 101 node[tot].t=time; 102 node[tot].type=4; 103 node[++tot].x=xx; 104 node[tot].y=y; 105 node[tot].t=time; 106 node[tot].type=5; 107 } 108 flag=read(); 109 } 110 CDQ(1,tot); 111 sort(node+1,node+tot+1,cmp_t); 112 for(int i=1;i<=cnt;i++) 113 { 114 int p=ask[i]; 115 int ans=node[p].k+node[p+1].k-node[p+2].k-node[p+3].k; 116 printf("%d\n",ans); 117 } 118 return 0; 119 }