bzoj 3323: [Scoi2013]多项式的运算.

3323: [Scoi2013]多项式的运算

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 412  Solved: 148
[Submit][Status][Discuss]

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。

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

#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
#define maxn 100010
#define mod 20130426ll
int ch[maxn][2],fa[maxn];
int size[maxn],n,root;
ll a[maxn],add[maxn];
ll mul[maxn],mi,ans;
inline int input() {
	int x=0,a=1;char c=getchar();
	for(;c<‘0‘||c>‘9‘;c=getchar())
		if(c==‘-‘) a=-1;
	for(;c>=‘0‘&&c<=‘9‘;c=getchar())
		x=x*10+c-‘0‘;
	return x*a;
}
inline void updata(int x) {
	int lc=ch[x][0],rc=ch[x][1];
	size[x]=size[lc]+size[rc]+1;
	return;
}
inline void pushdown(int x) {
	int lc=ch[x][0],rc=ch[x][1];
	ll &Mul=mul[x],&Add=add[x];
	a[x]=(a[x]*Mul)%mod;
	a[x]=(a[x]+Add)%mod;
	add[lc]=(add[lc]*Mul+Add)%mod;
	add[rc]=(add[rc]*Mul+Add)%mod;
	mul[lc]=(mul[lc]*Mul)%mod;
	mul[rc]=(mul[rc]*Mul)%mod;
	Mul=1ll,Add=0ll;
	return;
}
inline int son(int x) {
	return ch[fa[x]][1]==x;
}
void rotate(int x) {
	int y=fa[x],z=fa[y];
	int b=son(x),c=son(y),a=ch[x][!b];
	if(z) ch[z][c]=x;
	else root=x;
	fa[x]=z;
	if(a) fa[a]=y;
	ch[y][b]=a;
	ch[x][!b]=y;
	fa[y]=x;
	updata(y);
	updata(x);
	return;
}
void splay(int x,int i) {
	while(fa[x]!=i) {
		int y=fa[x],z=fa[y];
		if(z==i) {
			pushdown(y);
			pushdown(x);
			rotate(x);
		} else {
			pushdown(z);
			pushdown(y);
			pushdown(x);
			if(son(x)==son(y)) {
				rotate(y);
				rotate(x);
			} else {
				rotate(x);
				rotate(x);
			}
		}
	}
	return;
}
int getkth(int x,int k) {
	int lc=ch[x][0];
	if(size[lc]+1==k) return x;
	if(size[lc]>=k) return getkth(lc,k);
	return getkth(ch[x][1],k-size[lc]-1);
}
void plus(int L,int R,int v) {
	int l=getkth(root,L);
	int r=getkth(root,R+2);
	splay(l,0);
	splay(r,l);
	int x=ch[r][0];
	add[x]=(add[x]+v)%mod;
	return;
}
void multiply(int L,int R,int v) {
	int l=getkth(root,L);
	int r=getkth(root,R+2);
	splay(l,0);
	splay(r,l);
	int x=ch[r][0];
	add[x]=(add[x]*v)%mod;
	mul[x]=(mul[x]*v)%mod;
	return;
}
void multiply_plus(int L,int R) {
	int rm=getkth(root,R);
	int r1=getkth(root,R+1);
	int r2=getkth(root,R+2);
	splay(rm,0);
	splay(r2,rm);
	pushdown(rm);
	pushdown(r2);
	pushdown(r1);
	a[r2]=(a[r2]+a[r1])%mod;
	ch[r2][0]=0;
	size[r2]--;
	size[rm]--;
	int lm=getkth(root,L);
	int l=getkth(root,L+1);
	splay(lm,0);
	splay(l,lm);
	pushdown(lm);
	pushdown(l);
	ch[l][0]=r1;
	fa[r1]=l;
	size[r1]=1;
	size[l]++;
	size[lm]++;
	a[r1]=0;
	add[r1]=0;
	mul[r1]=1;
	return;
}
void dfs(int x,ll v) {
	pushdown(x);
	int lc=ch[x][0],rc=ch[x][1];
	if(lc) dfs(lc,v);
	if(mi==-1) mi=1;
	else {
		ans=(ans+a[x]*mi)%mod;
		mi=(mi*v)%mod;
	}
	if(rc) dfs(rc,v);
	return;
}
void query(ll v) {
	ans=0,mi=-1;
	dfs(root,v);
	printf("%lld\n",ans);
	return;
}
void init(int n) {
	n+=5;
	root=1;
	for(int i=1;i<n;i++) ch[i][1]=i+1;
	for(int i=2;i<=n;i++) fa[i]=i-1;
	for(int i=n;i>=1;i--) {
		updata(i);
		mul[i]=1ll;
	}
	return;
}
int main() {
	n=input();
	for(init(n);n>=1;n--) {
		char op[10];
		scanf("%s",op);
		int x=input(),len=strlen(op);
		if(op[0]==‘m‘) {
			int y=input();
			if(len==3) {
				int z=input();
				multiply(x+1,y+1,z);
			} else multiply_plus(x+1,y+1);
		} else if(op[0]==‘a‘) {
			int y=input(),z=input();
			plus(x+1,y+1,z);
		} else query((ll)x);
	}
	return 0;
}

  

时间: 2024-10-10 00:33:11

bzoj 3323: [Scoi2013]多项式的运算.的相关文章

SCOI2013 多项式的运算 (BZOJ 3323)

似乎仍然不能附传送门..权限题T_T... 3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec  Memory Limit: 64 MB Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0 + a1 * x^1 + a2 *

BZOJ3323: [Scoi2013]多项式的运算

3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec  Memory Limit: 64 MBSubmit: 128  Solved: 33[Submit][Status] Description 某天,mzry1992 一边思考着一个项目问题一边在高速公路上骑着摩托车.一个光头踢了他一脚,摩托车损坏,而他也被送进校医院打吊针.现在该项目的截止日期将近,他不得不请你来帮助他完成这个项目.该项目的目的是维护一个动态的关于x 的无穷多项式F(x) = a0 * x^0

SCOI2013 多项式的运算

---恢复内容开始--- 又是一道裸数据结构题. 之前受序列操作的蛋疼写法影响,只用一个tag,不知道怎么记,之后看了下别人的,终于领悟要用两个tag,一个add,一个mul,维护相当简单,想清楚就行. 简单说下解法. add mul就是一般的将[L,R]split出来然后打tag. mulx:我将[L,R+1]split出来,然后这一段split成l:[L,R-1],mid:[R,R],r[R+1,R+1],然后把mid的系数加到r上,把mid的系数赋为0,然后merge(mid,l,r);这

多项式相加运算

 多项式相加运算,使用链表实现,代码仍需要改善,这里先初步做个记录 //实现多项式的表示及相加 by Denis #include <stdio.h> #include <malloc.h> #define ture 1 #define false 0 typedef int ElemType; typedef struct LNode{ ElemType coef; //系数 int expn; //指数 struct LNode *next; }polynomia; pol

多项式加法运算 使用链表实现

/* 多项式加法运算 使用链表实现 */ #include <iostream> using namespace std; //使用不带头结点的单向链表,按照指数递减的顺序排列 typedef struct PolyNode { int coef; //系数 int expon; //指数 PolyNode *link; //指向下一个节点的指针 }*polynomial, npolynomial; polynomial PolyAdd(polynomial p1, polynomial p2

Calculation Of Polynomial(多项式的运算) C++

本文实现了一个多项式的类,类中重载了多项式的加法.减法.乘法,并且对>> 和 << 进行了重载. 其中多项式的输入(输出)格式为: K  N1 aN1 N2 aN2 ... NK aNK 其中K表示多项式的系数,NK表示第K项的系数aNk相应的系数,并且多项式的系数递减的序列. 1 //polynomial.h 2 #include <iostream> 3 #include <vector> 4 #include <iomanip> 5 6 c

一元稀疏多项式加法运算

描述: 设计一个一元稀疏多项式加法运算器,完成多项式a和b相加,建立多项式a+b. 输入说明: 一组输入数据,所有数据均为整数.第1行为2个正整数n,m,其中 n表示第一个多项式的项数,m表示第二个多项式的项数:第2行包含2n个整数,每两个整数分别表示第一个多项式每一项的系数和指数:第3行包含2m个整数,每两个整数分别表示第二个多项式每一项的系数和指数.(注:序列按指数升序排列) 输出说明: 在一行以类多项式形式输出结果,指数按从低到高的顺序.注意,系数值为1的非零次项的输出形式中略去系数1,如

BZOJ 3456 城市规划 多项式求ln

题意:链接 方法:多项式求ln 解析: 毒瘤题的倒数第二个- -! md毒瘤题都做完后再回来写题解真是爽歪歪 先看这道题怎么做. 首先一个简单无向图的边的个数是C(n,2),然后那么我们的选择就有2C(n,2)种. 然后我们再考虑简单无向连通图的方案数为fi. f[i]=2C(i,2)?∑i?1j=1f[j]?C(i?1,j?1)?2C(i?j,2) 上面的式子其实没啥卵用- 现在我们这么来考虑. 看如上大爷给出的PPT. 其实这个正体现了划分和被划分的关系. 对于简单无向图来说,简单无向连通图

BZOJ 3933 CQOI2015 多项式 高精度

题目大意戳这里 用x替换式子中的x-t得到: ∑nk=0ak(x+t)k=∑nk=0bkxk 于是可以得到: bm=∑nk=mCk?mktk?mak=∑n?mi=0Cim+itiam+i 其中ai=(209?1234i mod 3388+3181) mod 3389 然后...出题人我*尼玛... #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> usi