洛谷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 }
AC代码:

 

posted @ 2018-04-19 12:36  huyufeifei  阅读(164)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

ReadEra 阅读书籍

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜