BZOJ 3323: [Scoi2013]多项式的运算

Description

某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车。一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针。现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目。该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 * x^2 + ... ,这个多项式初始时对于所有i有ai = 0。
操作者可以进行四种操作:
1.  将x^L 到x^R 这些项的系数乘上某个定值v
2.  将x^L 到x^R 这些项的系数加上某个定值v
 
3.  将x^L 到x^R 这些项乘上x变量
4.  将某个定值v代入多项式F(x),并输出代入后多项式的值,之后多项式还原为代入前的状况
经过观察,项目组发现使用者的操作集中在前三种,第四种操作不会出现超过10次。mzry1992 负责这个项目的核心代码,你能帮他实现么。

Input

输入的第一行有一个整数n 代表操作的个数。
接下来n 行,每行一个操作,格式如下:
mul L R v 代表第一种操作
add L R v 代表第二种操作
mulx L R 代表第三种操作
query v 代表第四种操作

对于30% 的数据:N <= 5000,0 <= L <= R <= 5000,0 <= v <= 10^9
另有20% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9,没有mulx 操作
剩下的50% 的数据:N <= 10^5,0 <= L <= R <= 10^5,0 <= v <= 10^9

Output

对于每个query 操作,输出对应的答案,结果可能较大,需要模上20130426。

Sample Input

6
add 0 1 7
query 1
mul 0 1 7
query 2
mulx 0 1
query 3

Sample Output

14
147
588
Hint
操作一之后,多项式为F(x) = 7x + 7。
操作三之后,多项式为F(x) = 49x + 49。
操作五之后,多项式为F(x) = 49x^2 + 49x。

HINT

应上传者要求,此系列试题不公开,如有异议,本站将删除之。


呵呵。

呵呵呵呵呵呵呵呵呵呵。

呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵呵。

,b


这尼玛题说多了都是泪啊。

去年怒挂看错题。

现在来做,TLE!!!!!

UESTC:

15907 sdogsq 126 Accepted 7700 KB 932 MS C++ 3156 B
无鸭梨啊!


万恶的BZOJ:

597502sdogsq3323Time_Limit_Exceed12532 kb13044 msC++/Edit3664 B2014-04-02 16:53:41
597495sdogsq3323Time_Limit_Exceed14876 kb13328 msC++/Edit3452 B2014-04-02 16:46:48
597472sdogsq3323Wrong_Answer10188 kb2576 msC++/Edit3501 B2014-04-02 16:27:52
597436sdogsq3323Time_Limit_Exceed12528 kb13056 msC++/Edit4074 B2014-04-02 16:08:55
597414sdogsq3323Time_Limit_Exceed12528 kb13044 msC++/Edit3388 B2014-04-02 15:57:24
597401sdogsq3323Time_Limit_Exceed12528 kb13712 msC++/Edit3324 B2014-04-02 15:51:07
597363sdogsq3323Time_Limit_Exceed18700 kb13964 msC++/Edit3385 B2014-04-02 15:35:44
597352sdogsq3323Wrong_Answer18700 kb1560 msC++/Edit3385 B2014-04-02 15:24:22

我XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX!!!!!!!!!!!!!!!!!

悲愤之情已无法停留在溢于言表的层面了!!!

神级BZOJ一共开12s ,去年考场4s/点!!!!!



哎。

上代码。优化了一百次的代码。

#include <cstdio>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
#define per(i,r,l) for (int i=r;i>=l;--i)
typedef long long LL;
int getx(){
	char c;int x;
	for (c=getchar();c<'0'||c>'9';c=getchar());
	for (x=0;c>='0'&&c<='9';c=getchar())
		x=(x<<3)+(x<<1)+c-'0';
	return x;
}
const int MP=100000;
const LL MOD=20130426;
const int MAX_N=MP*3;
int ch[MAX_N][2],pre[MAX_N],size[MAX_N];
int tal=0,root=0;
LL add[MAX_N],mul[MAX_N],key[MAX_N];
#define up(x) (size[x]=size[ch[x][0]]+size[ch[x][1]]+1)
#define Mmod(i,j) if ((i*=j)>=MOD) i%=MOD
#define Amod(i,j) if ((i+=j)>=MOD) i-=MOD
inline void down(int x){
	if (mul[x]!=1){
		Mmod(mul[ch[x][0]],mul[x]);
		Mmod(mul[ch[x][1]],mul[x]);
		Mmod(add[ch[x][0]],mul[x]);
		Mmod(add[ch[x][1]],mul[x]);
		Mmod(key[ch[x][0]],mul[x]);
		Mmod(key[ch[x][1]],mul[x]);
		mul[x]=1;
		}
	if (add[x]!=0){
		Amod(add[ch[x][0]],add[x]);
		Amod(add[ch[x][1]],add[x]);
		Amod(key[ch[x][0]],add[x]);
		Amod(key[ch[x][1]],add[x]);
		add[x]=0;
		}
}
void Rotate(int x,bool f){
	int y=pre[x];
	pre[ch[x][f]]=y;
	pre[x]=pre[y];
	pre[y]=x;
	if (pre[x]) ch[pre[x]][ch[pre[x]][1]==y]=x;
	ch[y][!f]=ch[x][f];
	ch[x][f]=y;
	up(y);
}
void splay(int x,int goal){
	while (pre[x]!=goal){
		if (pre[pre[x]]==goal)
			Rotate(x,ch[pre[x]][0]==x);
		else{
			int y=pre[x],z=pre[y];
			bool f=(ch[z][0]==y);
			if (ch[y][f]==x)
				Rotate(x,!f),Rotate(x,f);
			else
				Rotate(y,f),Rotate(x,f);
		 }
		}
	up(x);
	if (goal==0) root=x;
}
void RTO(int k,int goal){
	int v=root;
	while (v){
		down(v);
		int tp=size[ch[v][0]]+1;
		if (tp==k) break;
		v= tp<k ? k-=tp,ch[v][1]:ch[v][0];
		}
	splay(v,goal);
}
inline void range(int l,int r){
	RTO(l+1,0);RTO(r+3,root);
}
inline void Newnode(int &v,int fa){
	v=++tal;
	pre[v]=fa,size[v]=1;
	mul[v]=1,add[v]=0;
}
void build(int &v,int l,int r,int fa){
	if (l>r) return;
	Newnode(v,fa);
	int mid=l+r>>1;
	build(ch[v][0],l,mid-1,v);
	build(ch[v][1],mid+1,r,v);
	up(v);
}
void Add(int l,int r,LL x){
	x%=MOD;
	range(l,r);
	Amod(add[ch[ch[root][1]][0]],x);
	Amod(key[ch[ch[root][1]][0]],x);
}
void Mul(int l,int r,LL x){
	x%=MOD;
	range(l,r);
	Mmod(mul[ch[ch[root][1]][0]],x);
	Mmod(add[ch[ch[root][1]][0]],x);	
	Mmod(key[ch[ch[root][1]][0]],x);
}
void Mulx(int l,int r){
	range(r,r);
	int x=ch[ch[root][1]][0],y=pre[x];
	ch[y][0]=0;
	Amod(key[y],key[x]);
	up(y),up(root);
	range(l,l-1);
	Newnode(ch[ch[root][1]][0],ch[root][1]);
}
int mx=0;
LL nx,res,x;
bool fir;
void bl(int v){
	if (!v) return;
	down(v);
	bl(ch[v][0]);
	if (!fir) fir=true;
		else{(res+=nx*key[v])%=MOD;Mmod(nx,x);}
	bl(ch[v][1]);
}
void query(LL xx){
	x=xx;
	nx=1,res=0;fir=false;
	bl(root);  //询问一次O(n)
//	rep(i,2,mx+3){//询问一次O(NlogN)
//		RTO(i,0);
//		(res+=nx*key[root])%=MOD;
//		Mmod(nx,x);
//		}
	printf("%I64d\n",res);
}
int n;
char opt[10];
int main(){
	freopen("a.in","r",stdin);
	freopen("a.out","w",stdout);
	build(root,0,MP+3,0);
	n=getx();
	rep(i,1,n){
		scanf("%s",opt+1);
		if (opt[1]=='a'){
			int l=getx(),r=getx(),x=getx();
			mx=mx>r?mx:r;
			Add(l,r,x);
			}else
		if (opt[1]=='q'){
			int x=getx();
			query(x);
			}else
		if (opt[4]=='x'){
			int l=getx(),r=getx();
			mx=mx>r+1?mx:r+1;
			Mulx(l,r);
			}else{
			int l=getx(),r=getx(),x=getx();
			mx=mx>r?mx:r;
			Mul(l,r,x);
			}
		}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值