码迷,mamicode.com
首页 > 其他好文 > 详细

cogs2264 魔法传输

时间:2017-09-19 00:15:56      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:span   大众   来源   差分   ==   传输   define   char   efault   

2264. 魔法传输

★★★   输入文件:magics.in   输出文件:magics.out   简单对比
时间限制:1 s   内存限制:256 MB

【题目描述】

 

自从看了《哈利波特》,小Y就十分渴望获得魔法值。于是他和一群向往魔法的孩子(当然这些孩子们都是不会魔法的)来到了哈利波特的家,大家坐成一排。哈利波特会不时的给大家传输魔法。

哈利每次会选择一个区间,给这个区间里的孩子们传输魔法:最左边的孩子给一点,第二个给两点……哈利有时会突然问你某一个孩子已经有了多少魔法。

 

【输入格式】

 

第一行两个正整数 N,M,表示有 N 个孩子,哈利有 M 次操作。

接下来 M 行,每行代表一个操作。第一个字符为 ci,若 ci=‘C’则此次操作为传送魔法操作,接下来会有两个整数Li,Ri,表示此次送魔法值的区间。若 ci=‘Q’则此次操作为询问操作,接下来一个整数xi,表示询问第xi个孩子当前的魔法值。

 

【输出格式】

对于每组询问输出一行,仅包含一个整数,表示答案对 1,000,000,007 取模(mod)的结果。

【样例输入】

3 4	
C 1 3	
Q 2	
C 2 3	
Q 2

【样例输出】

2
3

【提示】

 

【数据规模】

对于 30%的数据,N,M≤1,000;

对于 100%的数据,N,M≤100,000。

 

【来源】

在此键入。

区间修改的模板题啊。。。难度竟然给那么高。。。我贴这道题主要不是它有多难..而是我的解法好像和大众不太一样

贴上我的代码

#include<bits/stdc++.h>
#define ll long long
#define mid ((l+r)>>1)
#define ls o<<1
#define rs o<<1|1
using namespace std;
const int ma=100005;
const int mod=1000000007;
ll n,m,f[ma<<2],lazy1[ma<<2],lazy2[ma<<2];
void change1(ll l,ll r,ll o,ll L,ll R,ll x){
	if(l>=L&&r<=R){
		lazy1[o]+=x;
		lazy1[o]%=mod;
		return ;
	}
	if(mid>=L)change1(l,mid,ls,L,R,x);
	if(mid<R)change1(mid+1,r,rs,L,R,x);
}
void change2(ll l,ll r,ll o,ll L,ll R,ll x){
	if(l>=L&&r<=R){
		lazy2[o]+=x;
		lazy2[o]%=mod;
		return ;
	}
	if(mid>=L)change2(l,mid,ls,L,R,x);
	if(mid<R)change2(mid+1,r,rs,L,R,x);
}
ll q(ll l,ll r,ll o,ll x,ll sum1,ll sum2){
	if(l==r){
		return (l*(lazy1[o]+sum1)%mod-(lazy2[o]+sum2)%mod+mod)%mod;
	}
	if(mid>=x)return q(l,mid,ls,x,(sum1+lazy1[o])%mod,(sum2+lazy2[o])%mod)%mod;
	else return q(mid+1,r,rs,x,(sum1+lazy1[o])%mod,(sum2+lazy2[o])%mod)%mod;
}
int main()
{
	freopen("magics.in","r",stdin);
	freopen("magics.out","w",stdout);
//	freopen("1.txt","r",stdin);
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;i++){
		char s[10];
		ll x,y;
		scanf("%s",s);
		if(s[0]==‘C‘){
			scanf("%lld%lld",&x,&y);
			change1(1,n,1,x,y,1);
			change2(1,n,1,x,y,x-1);
		}
		else {
			scanf("%lld",&x);
			printf("%lld\n",q(1,n,1,x,0,0));
		}
	}
	return 0;
}

  大家好像解法分为两大阵营吧,差分+线段树区间修改,分块

我这完全就没用到差分。。。我觉得我应该跑的很快才对啊,,结果榜都上不了

对于任意一个点,我们维护两个lazy值,第一个记录当前区间被若干次修改,每次修改左端点的值之和,第二个记录这个点被加了多少次,对于任意一次查询,我们只需要用他 对应坐标*lazy2-lazy1,即可得到被修改后的值

突然就想到这个奇怪的解法...反正后来看评论区是没看到跟我一样的..旁边的cmath用我一倍长的代码跑的比我慢了一倍

cogs2264 魔法传输

标签:span   大众   来源   差分   ==   传输   define   char   efault   

原文地址:http://www.cnblogs.com/Turkeyghb/p/7545663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!