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);这里注意如果L==R将会出现问题,于是这里我特判了一下。
还是就是见乘就得加long long.....
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int Maxn=+,Mod=,MaxR=;
int _a[Maxn],cnt;
inline void fadd(int&a,int b){
a+=b;if(a>Mod)a-=Mod;
}
struct node{
int v,sz,add,mul;//itself isn't in it
node*ch[];
node(){
sz=v=add=;mul=;
}
inline void maintain(){
sz=ch[]->sz+ch[]->sz+;
}
inline int cmp(int k){
if(ch[]->sz+==k)return -;
return k>ch[]->sz+;
}
inline void AddTag(int Add,int Mul){
v=(long long)v*Mul%Mod;
fadd(v,Add);
mul=(long long)mul*Mul%Mod;//注意long long
add=(long long)add*Mul%Mod;//注意long long
fadd(add,Add);
}
inline void down(){
ch[]->AddTag(add,mul);
ch[]->AddTag(add,mul);
add=;mul=;
}
}da[Maxn],*root,*null;int tot;
inline void rotate(node*&o,int d){
node*t=o->ch[d];
o->ch[d]=t->ch[d^];
t->ch[d^]=o;
o->maintain();
(o=t)->maintain();
}
void splay(node*&o,int k){
o->down();
int d=o->cmp(k);
if(d==-)return;
if(d)k-=o->ch[]->sz+;
node*&p=o->ch[d];
p->down();
int d2=p->cmp(k);
if(d2!=-){
if(d2)k-=p->ch[]->sz+;
splay(p->ch[d2],k);
if(d2!=d)rotate(p,d2);
else rotate(o,d);
}
rotate(o,d);
}
void build(node*&o,int l,int r){
if(l>r){
o=null;
return;
}
int mid=(l+r)>>;
o=da+ ++tot;
build(o->ch[],l,mid-);
build(o->ch[],mid+,r);
o->maintain();
}
void print(node*o){
if(o==null)return;
o->down();
print(o->ch[]);
++cnt;
if(cnt>= && cnt<=MaxR+)_a[cnt-]=o->v;
// printf("%d\n",o->v);
print(o->ch[]);
}
inline int calc(int x,const int*a){
int ret=a[MaxR];
for(int i=MaxR;i>=;i--){
ret=(long long)ret*x%Mod;
fadd(ret,a[i]);
}
return ret;
}
inline void split(node*o,int k,node*&l,node*&r){
splay(o,k);
r=o->ch[];
(l=o)->ch[]=null;
l->maintain();
}
inline node*merge(node*l,node*r){
splay(l,l->sz);
l->ch[]=r;
l->maintain();
return l;
}
int get_tp(char *opt){
if(opt[]=='a')return ;
if(opt[]=='m')return opt[]?:;
return ;
}
int main(){
freopen("polynomial.in","r",stdin);
freopen("polynomial.out","w",stdout); int tp,L,R,V,n;
null=da;
null->ch[]=null->ch[]=null;
build(root,,MaxR+);
node*o,*l,*r,*mid;
char opt[]={};
for(scanf("%d\n",&n);n--;){
scanf("%s",opt);
tp=get_tp(opt);
if(tp<=){
scanf("%d%d%d",&L,&R,&V);V%=Mod;
split(root,L+,l,o);
split(o,R-L+,mid,r);
if(tp==)mid->AddTag(V,);
else mid->AddTag(,V);
root=merge(merge(l,mid),r);
}
else if(tp==){
scanf("%d%d",&L,&R);
split(root,L+,l,o);
split(o,R-L+,mid,r);
if(R==L){//这里必须特判
splay(mid,);
mid->down();
mid->ch[]->down();
fadd(mid->ch[]->v,mid->v);
mid->v=;
}else{
node*_o,*_l,*_r,*_mid;
split(mid,mid->sz-,_l,_o);
split(_o,,_mid,_r);
_mid->down();
_r->down();
fadd(_r->v,_mid->v);
_mid->v=;
mid=merge(merge(_mid,_l),_r);
}
root=merge(merge(l,mid),r);
}
else {
scanf("%d",&V);V%=Mod;
cnt=;
print(root);
printf("%d\n",calc(V,_a));
}
} return ;
}
SCOI2013 多项式的运算的更多相关文章
- BZOJ3323: [Scoi2013]多项式的运算
3323: [Scoi2013]多项式的运算 Time Limit: 12 Sec Memory Limit: 64 MBSubmit: 128 Solved: 33[Submit][Status ...
- 2019.03.29 bzoj3323: [Scoi2013]多项式的运算(非旋treap)
传送门 题意:定义一个无穷项的多项式f(x)f(x)f(x),初始各项系数都为0,现在有几种操作 将xLx^LxL到xRx^RxR这些项的系数乘上某个定值v 将xLx^LxL到xRx^RxR这些项的系 ...
- LUOGU3278 [SCOI2013]多项式的运算
一次AC.吼啊. BZOJ权限QAQ 区间加和乘打标记,区间乘x就是区间移动,平衡树解决即可. 查询直接遍历一遍然后算出来 // It is made by XZZ #include<cstdi ...
- luogu3278/bzoj3323 多项式的运算 (splay)
mulx的操作,其实就是给r+1的系数+=r的系数,然后删掉r,把l~r-1向右移一位,再插一个0到原来的位置 splay维护区间加和区间乘就好了 (一定要注意做事的顺序,一件事都做完了再去做别的,否 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- MATLAB符号运算 分类: 图像处理 2015-07-31 22:53 3人阅读 评论(0) 收藏
1.符号运算 使用MATLAB可以进行多项式乘除运算,也可以进行因式分解. 例1. 多项式乘除运算(x+3)3 >> syms x; >> expand((x+3)^3) an ...
- MATLAB符号运算
1.符号运算 使用MATLAB可以进行多项式乘除运算,也可以进行因式分解. 例1. 多项式乘除运算(x+3)3 >> syms x;>> expand((x+3)^3) ans ...
- 多项式相关&&生成函数相关&&一些题目(updating...)
文章目录 多项式的运算 多项式的加减法,数乘 多项式乘法 多项式求逆 多项式求导 多项式积分 多项式取对 多项式取exp 多项式开方 多项式的除法/取模 分治FFT 生成函数 相关题目 多项式的运算 ...
- java-四则运算二
1.实验目的:是否有乘除法,括号,多项式运算. 2.思路:利用简单的循环switch语句进行循环输出随机数 3.程序源代码: package jiajianchengchu; import java. ...
随机推荐
- centos 6.x 安装redis
1.yum 安装 yum install redis 如果提示找不到包的话 可以yum install epel-release 先安装epel第三方库 2.源码安装 https://redis ...
- SGU 143.Long Live the Queen(女王万岁)
时间限制:0.25s 空间限制:4M 题意: 有n(n<=16000)个小镇,每两个小镇有且仅有一条路径相连.每个小镇有一个收益x(-1000<=x<=1000). 现在要求,选择一 ...
- visualSVN server库迁移(转)
转自:http://blog.csdn.net/yuhuijun_1/article/details/9762683 首先,VisualSVN Server Manager,包含两个路径,一个是安装路 ...
- Atom package安装失败的解决方案
cd ~/.atom/package git clone [package url] cd [package name] apm install [package name] if lack some ...
- 设置session的生命周期(php)
PHP中,Session变量保存在服务器端(默认以文件格式保存),而Session ID以cookie形式保存在客户端. 销毁session的方法有2种 第一种是通过程序 session_destor ...
- 谈谈android 布局 的优化
来自:http://www.cnblogs.com/youxilua/archive/2012/05/08/2489414.html 导言 设配android的屏幕一定是一个噩梦,就好比那些搞网页设计 ...
- Keil的使用-1创建项目和工程
下载keil,注意不要使用MDK版本(主要是arm开发使用),大小约54M 安装过程不再详述 安装Keil成功并运行后,新建项目, 创建新项目,然后弹出下图,选择对应的单片机芯片(双击) ...
- openerp report image
webkit : 再mako 文件中插入以下代码, <% %>标签用于再mako中定义代码或者函数. 然后 ${ embed_image('图片类型', 图片字段 , 宽度,高度) } ...
- openshif ssh proxy
最近google又被墙了.没办法 1:注册一个openshift账号.申请注册一个app,获取一个免费主机. https://www.openshift.com/ 2:去PuTTY官方网站下载pL ...
- swfobject.js IE兼容问题
错误代码 在562行左右 / add style rule if (ua.ie && ua.win) { if (dynamicStylesheet && typeof ...