程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治詢問)

BZOJ 1176([Balkan2007]Mokia-CDQ分治-分治詢問)

編輯:C++入門知識

1176: [Balkan2007]Mokia
Time Limit: 30 Sec  Memory Limit: 162 MB
Submit: 185  Solved: 94
[Submit][Status]
Description
維護一個W*W的矩陣,每次操作可以增加某格子的權值,或詢問某子矩陣的總權值。 修改操作數M<=160000,詢問數Q<=10000,W<=2000000。
Input
Output
Sample Input
0 4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3

Sample Output
3
5

HINT
Input file Output file Meaning
0 4 Table size is , filled with zeroes.

1 2 3 3 Add 3 customers at (2, 3).
2 1 1 3 3 Query sum of rectangle , .

3 Answer.
1 2 2 2 Add 2 customers at (2, 2).
2 2 2 3 4 Query sum of rectangle , .

5 Answer
3 Exit your program.

 

 

 

 


裸CDQ...1A

注意幾個關鍵部分的寫法

步驟:

1.讀入詢問,按x排序

2.將[L,R]中的數分為前部分操作,後部分操作(各部分仍保持X升序)

3.將前面對後面的影響記錄ans

4.復原影響

5.遞歸[L,M],[M+1,R]

 


 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#include<cmath>
#include<cctype>
#include<cassert>
#include<climits>
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Rep(i,n) for(int i=0;i<n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,n) for(int i=n;i;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define RepD(i,n) for(int i=n;i>=0;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define MEMI(a) memset(a,127,sizeof(a))
#define MEMi(a) memset(a,128,sizeof(a))
#define INF (2139062143)
#define F (1000000009)
#define MAXM (640000+10)
#define MAXQ (10000+10)
#define MAXN (2000000+10) 
typedef long long ll;
int n,m,q;
ll ans[MAXQ];
struct comm
{
   int no,x,y,v,q,type;
   comm():no(0),x(0),y(0),v(0),q(0),type(0){}
   comm(int _no,int _x,int _y,int _v,int _q,int _type):no(_no),x(_x),y(_y),v(_v),q(_q),type(_type){}
   friend bool operator<(comm a,comm b){return a.x<b.x;}      
}ask[MAXM];
struct arr_tree
{
   ll a[MAXN];
   arr_tree(){memset(a,0,sizeof(a));}
   void add(int x,ll c)
   {
      for(int i=x;i<=n;i+=i&(-i)) a[i]+=c;
   }
   int qur(int x)
   {
      ll ans=0;
      for(int i=x;i;i-=i&(-i)) ans+=a[i];
      return ans;   
   }
   void clear()
   {
      memset(a,0,sizeof(a));
   }
}T;
comm tmp[MAXM];
void solve(int l,int r)
{
   if (l==r) return;
   int m=l+r>>1;
   int s1=l-1,s2=m;
   Fork(i,l,r) tmp[ask[i].no<=m?++s1:++s2]= ask[i];
   memcpy(ask+l,tmp+l,sizeof(comm)*(r-l+1));
   int now=l;
   Fork(i,m+1,r) //遍歷詢問 
   {
      if (ask[i].type==2)
      {
         while (ask[now].x<=ask[i].x&&now<=m)
         {
            if (ask[now].type==1) T.add(ask[now].y,ask[now].v);
            now++;
         }
         ans[ask[i].q]+=ask[i].v*T.qur(ask[i].y);         
      }
   }
   now--;
   while (l<=now) {if (ask[now].type==1) T.add(ask[now].y,-ask[now].v);now--;}
   solve(l,m),solve(m+1,r);
}
bool work()
{
   scanf("%d",&n);
   int type,no=0,x,y,x1,y1,x2,y2,v,q=0;
   memset(ans,0,sizeof(ans));T.clear();
   while (scanf("%d",&type))
   {
      if (type==0||type==3) break;
      else if (type==1)
      {
         scanf("%d%d%d",&x,&y,&v);
         no++;ask[no]=comm(no,x,y,v,0,1);
      }
      else if (type==2)
      {
         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);q++;
         no++;ask[no]=comm(no,x1-1,y1-1,1,q,2);
         no++;ask[no]=comm(no,x2,y2,1,q,2);
         no++;ask[no]=comm(no,x1-1,y2,-1,q,2);
         no++;ask[no]=comm(no,x2,y1-1,-1,q,2);         
      }
   }
   sort(ask+1,ask+1+no);
   solve(1,no);
   For(i,q) cout<<ans[i]<<endl;
   return type==0;
}
int main()
{
   //freopen("bzoj1176.in","r",stdin);
   int type;
   scanf("%d",&type);if (type==3) return 0;
   while (work());
   //cout<<"END"<<endl;while (1);
   return 0;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved