cogs 1752. [BOI2007]摩基亚Mokia
2017-07-05 19:49
344 查看
题目链接:http://www.cogs.pro/cogs/problem/problem.php?pid=1752
cdq分治模版题。就是处理前缀和的时候这里变成了矩阵前缀和。我们采用扫描线的方法,用树状数组来维护一个矩阵的前缀和。
然后对于一个询问,我们采用矩阵前缀和的形式来处理这个询问,转化为4个操作。也就是对4个矩阵的处理。
然后看代码就可以了。
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 2e5+7;
typedef long long LL;
int n;
struct node
{
int x,y;
int qid;
int val;
int type;
node(){};
node(int X,int Y,int Val,int Type,int Qid = 0)
{
x = X;
y = Y;
val = Val;
type = Type;
qid = Qid;
}
bool operator <= (const node &a)const
{
return x == a.x?type < a.type : x < a.x;
}
} p[MAXN],temp[MAXN];
LL ans[10005];
LL val[MAXN*10];
void add(int x,int y)
{
for(; x <= n; x += x&-x)val[x] += y;
}
LL sum(int x)
{
LL ans = 0;
for(; x; x -= x&-x)ans += val[x];
return ans;
}
void cdq(int l,int r)
{
if(l == r)return;
int mid = (l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
int i = l, j = mid + 1;
int cnt = 0;
while(i <= mid && j <= r)
{
if(p[i] <= p[j])
{
if(p[i].type == 1)add(p[i].y,p[i].val);
temp[cnt++] = p[i++];
}
else
{
if(p[j].type == 2)ans[p[j].qid] += p[j].val*sum(p[j].y);
temp[cnt++] = p[j++];
}
}
while(j <= r)
{
if(p[j].type == 2)ans[p[j].qid] += p[j].val*sum(p[j].y);
temp[cnt++] = p[j++];
}
for(int ii = l ; ii < i ; ++ii)if(p[ii].type == 1)add(p[ii].y,-p[ii].val);//把树状数组清0,供下一次使用。
while(i <= mid)temp[cnt++] = p[i++];
for(int i = 0 ; i < cnt ; ++i)p[l++] = temp[i];
}
int main()
{
freopen("mokia.in","r",stdin);
freopen("mokia.out","w",stdout);
scanf("%*d%d",&n);
int x,y,t,c,x1,y1;
int id = 0 , qid = 0;
while(~scanf("%d",&t) && t!=3)
{
if(t == 1)
{
scanf("%d%d%d",&x,&y,&c);
p[++id] = node(x,y,c,1);
}
else
{
scanf("%d%d%d%d",&x,&y,&x1,&y1);
p[++id] = node(x-1,y-1,1,2,qid);
p[++id] = node(x1,y-1,-1,2,qid);
p[++id] = node(x-1,y1,-1,2,qid);
p[++id] = node(x1,y1,1,2,qid++);
}
}
cdq(1,id);
for(int i = 0 ; i < qid ; ++i)printf("%lld\n",ans[i]);
return 0;
}
cdq分治模版题。就是处理前缀和的时候这里变成了矩阵前缀和。我们采用扫描线的方法,用树状数组来维护一个矩阵的前缀和。
然后对于一个询问,我们采用矩阵前缀和的形式来处理这个询问,转化为4个操作。也就是对4个矩阵的处理。
然后看代码就可以了。
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 2e5+7;
typedef long long LL;
int n;
struct node
{
int x,y;
int qid;
int val;
int type;
node(){};
node(int X,int Y,int Val,int Type,int Qid = 0)
{
x = X;
y = Y;
val = Val;
type = Type;
qid = Qid;
}
bool operator <= (const node &a)const
{
return x == a.x?type < a.type : x < a.x;
}
} p[MAXN],temp[MAXN];
LL ans[10005];
LL val[MAXN*10];
void add(int x,int y)
{
for(; x <= n; x += x&-x)val[x] += y;
}
LL sum(int x)
{
LL ans = 0;
for(; x; x -= x&-x)ans += val[x];
return ans;
}
void cdq(int l,int r)
{
if(l == r)return;
int mid = (l+r)>>1;
cdq(l,mid);
cdq(mid+1,r);
int i = l, j = mid + 1;
int cnt = 0;
while(i <= mid && j <= r)
{
if(p[i] <= p[j])
{
if(p[i].type == 1)add(p[i].y,p[i].val);
temp[cnt++] = p[i++];
}
else
{
if(p[j].type == 2)ans[p[j].qid] += p[j].val*sum(p[j].y);
temp[cnt++] = p[j++];
}
}
while(j <= r)
{
if(p[j].type == 2)ans[p[j].qid] += p[j].val*sum(p[j].y);
temp[cnt++] = p[j++];
}
for(int ii = l ; ii < i ; ++ii)if(p[ii].type == 1)add(p[ii].y,-p[ii].val);//把树状数组清0,供下一次使用。
while(i <= mid)temp[cnt++] = p[i++];
for(int i = 0 ; i < cnt ; ++i)p[l++] = temp[i];
}
int main()
{
freopen("mokia.in","r",stdin);
freopen("mokia.out","w",stdout);
scanf("%*d%d",&n);
int x,y,t,c,x1,y1;
int id = 0 , qid = 0;
while(~scanf("%d",&t) && t!=3)
{
if(t == 1)
{
scanf("%d%d%d",&x,&y,&c);
p[++id] = node(x,y,c,1);
}
else
{
scanf("%d%d%d%d",&x,&y,&x1,&y1);
p[++id] = node(x-1,y-1,1,2,qid);
p[++id] = node(x1,y-1,-1,2,qid);
p[++id] = node(x-1,y1,-1,2,qid);
p[++id] = node(x1,y1,1,2,qid++);
}
}
cdq(1,id);
for(int i = 0 ; i < qid ; ++i)printf("%lld\n",ans[i]);
return 0;
}
相关文章推荐
- COGS1752 [BOI2007]摩基亚Mokia(CDQ分治 + 二维前缀和 + 线段树)
- COGS1752. [BOI2007]摩基亚Mokia(CDQ,树状数组)
- cogs 1752 [BOI2007]摩基亚Mokia(cdq分治+树状数组)
- COGS1752. [BOI2007]摩基亚Mokia
- Bzoj1176:Mokia&Cogs1752:[BOI2007]摩基亚Mokia
- Bzoj1176:Mokia&Cogs1752:[BOI2007]摩基亚Mokia
- cogs1752[boi2007]mokia 摩基亚 (cdq分治)
- 【COGS】1752. [BOI2007]摩基亚Mokia cdq分治模板题
- COGS1752. [BOI2007]摩基亚Mokia CDQ
- COJS 1752. [BOI2007]摩基亚Mokia
- 1752. [BOI2007]摩基亚Mokia (cdq分治模板题)
- 【COGS1752】 BOI2007—摩基亚Mokia
- cdq分治入门学习 cogs 1752 Mokia nwerc 2015-2016 G 二维偏序
- [BOI2007]摩基亚Mokia (cdq分治)
- cogs [BOI2007]摩基亚Mokia CDQ 分治
- [COGS 1752] 摩基亚Mokia
- 分治(CDQ):[BOI2007]摩基亚Mokia
- Cost of goods sold (COGS)
- spoj 1526 (BOI2007 day1) (费用提前计算相关的DP)
- 【DP】COGS 992. 宝物筛选