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. ...
随机推荐
- 网络编程(学习整理)---2--(Udp)实现简单的控制台聊天室
1.UDP协议: 总结一下,今天学习的一点知识点! UDP也是一种通信协议,常被用来与TCP协议作比较!我们知道,在发送数据包的时候使用TCP协议比UDP协议安全,那么到底安全在哪里呢?怎么理解呢! ...
- HDU5311 Hidden String
Problem Description Today is the 1st anniversary of BestCoder. Soda, the contest manager, gets a str ...
- C++ cout cerr 和 clog 的区别
我们都知道C++预定义了cin(标准输入流)和cout(标准输出流).但今天突然又蹦出来两个cerr(标准错误流(非缓冲))和clog(标准错误流(缓冲)),本着学习提高的态度在网上搜索了相关内容,下 ...
- Linux内存点滴:用户进程内存空间
原文出处:PerfGeeks 经常使用top命令了解进程信息,其中包括内存方面的信息.命令top帮助文档是这么解释各个字段的.VIRT , Virtual Image (kb)RES, Residen ...
- 使用程序往Neo4j导入CSV报错
今天在用程序向Neo4j导入csv文件时,报以下错误: java.net.ConnectException: Connection refused: connect java.rmi.ConnectE ...
- 面试后 follow up letter 分享
分享一下最近面试外企的follow up letter. Dear Mr. Xu, Thank you again for the time you and Mr. Guo spent wit ...
- Html5的<button>标签
1.标签是双标签,其内可添加文字,图片等复杂的样式. 2.不仅可以在表单中使用,还可以在其他块元素和内联元素中使用. 3.一般在input标签内添加name属性,否则提交后不显示.
- Leetcode: Reverse Integer 正确的思路下-要考虑代码简化
题目: Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have ...
- vim操作命令-笔记
显示行号:在vim命令行模式下输入 :set nu 或 :set number 取消显示行号:在vim命令行模式下输入 :set nonu 或 :set nonumber 查看文件编码格式: :set ...
- uboot main_loop函数分析
一.概述 main_loop()函数做的都是与具体平台无关的工作.主要包括的工作如下: (1)初始化启动次数限制机制 (2)Modem功能 (3)设置软件版本号 (4)启动延迟 (5)读取命令, ...