hdu 1892 See you~

时空隧道

本来是不打算写题解来着,但是它残忍的WA了我好多发委屈

这道题之所以写这么久...是因为研究了好久二维线段树..Orz 还是知道会MLE的情况下(所谓没事找事做),写了个模板,不知道能不能A题...


最后还是用的二维树状数组来着,线段树空间耗费too大了...


题目就是讲,最开始矩阵每个方格都有一本书~ 然后 有如下操作:

A X Y Z   在(x,y)增加z本书

D X Y Z  从(x,y)拿走z本书,如果不够z本,就拿走完。

S X Y N M  为由(x,y)(n,m)组成的矩阵里有多少本书,值得注意的是(x ,y) 不一定在(n,m)的左边,好吧,我在这里坑了

M X Y N M Z  从(x,y)出,拿走z本书到(n,m)处,若不够,则拿走(x,y)处的所有书到(n,m)处...吾在此处也坑了好久...

写这个是要提醒自己...c[x][y]!=a[x][y]  写着写着就写忘了...快哭了


code :

#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define LL __int64
#define ls v<<1
#define rs v<<1|1
//#define LOCAL
using namespace std;
const int INF=0x3ffffff;
const int MAXN=1100; 
int aa[MAXN][MAXN],cc[MAXN][MAXN];
int lowbit(int x){
	return x&(-x);
}

void add(int x,int y,int val)
{
	while(x<=1001)
	{
		int yy=y;
		while(yy<=1001)
		{
			cc[x][yy]+=val;
			yy+=lowbit(yy);
		}
		x+=lowbit(x);
	}
}

int sum(int x,int y)
{
	int rez=0;
	while(x)
	{
		int yy=y;
		while(yy)
		{
			rez+=cc[x][yy];
			yy-=lowbit(yy);
		}
		x-=lowbit(x);
	}
	return rez;
}
void Init(){
	for(int i=0;i<=1002;i++)
		for(int j=0;j<=1002;j++)
			cc[i][j]=0,aa[i][j]=1;
}

int main()
{
#ifdef LOCAL
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
#endif
	ios::sync_with_stdio(false);
	int t,a,b,c,d,e,n;
	char op[10];
	scanf("%d",&t);
	for(int cas=1;cas<=t;cas++)
	{
		Init();
		scanf("%d",&n);
		printf("Case %d:\n",cas);
		for(int i=1;i<=1001;i++)
			for(int j=1;j<=1001;j++)
				add(i,j,1);
		while(n--)
		{
			scanf("%s",op);
			if(op[0]=='S'){
				scanf("%d%d%d%d",&a,&b,&c,&d);
				int ans=0;
				if(a>c) swap(a,c);
				if(b>d) swap(b,d);
				ans=sum(c+1,d+1)+sum(a,b)-sum(a,d+1)-sum(c+1,b);
				printf("%d\n",ans);
			}
			else if(op[0]=='A'){
				scanf("%d%d%d",&a,&b,&c);
				aa[a+1][b+1]+=c;
				add(a+1,b+1,c);
			}
			else if(op[0]=='M'){
				scanf("%d%d%d%d%d",&a,&b,&c,&d,&e);
				if(aa[a+1][b+1]<e) {
					e=aa[a+1][b+1];
				}
				aa[a+1][b+1]-=e;
				add(a+1,b+1,-e);
				aa[c+1][d+1]+=e;
				add(c+1,d+1,e);
			}
			else if(op[0]=='D'){
				scanf("%d%d%d",&a,&b,&c);
				if(aa[a+1][b+1]<c) {
					c=aa[a+1][b+1];
				}
				aa[a+1][b+1]-=c;
				add(a+1,b+1,-c);
			}
		}
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值