【NOIP2013模拟联考7】数列
来源:互联网 发布:javascript分页代码 编辑:程序博客网 时间:2024/05/17 22:42
Description
给出一个序列,每个数由一个二元组(a,b)表示,有4中操作
1:把a值在l~r范围内的数乘上x再加上y
2:把b值在l~r范围内的数乘上x再加上y
3:询问a值在l~r范围内的数的和。
4:询问b值在l~r范围内的数的和。
n<=50000
Solution
写了一下午的常数优化,终于过掉了TAT
具体来说,很容易想到第一个分块。我们用每个块维护原块和排过序的块,那么我们2操作修改的就是每个块中的连续一段。1操作所覆盖的块由于对应关系可以直接打标记,剩下的自己手动修改就好了。
那么连续的区间标记呢?总不能用线段树吧?
好吧,一开始我用的就是线段树。。。结果跑的和暴力分数一样(出题人良心大大滴坏TAT)
其实,我们可以使用分块套分块(分块大法好!)
区间标记也用一个块来维护。
然后?然后你就去打吧。。。
Code
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define fo(i,a,b) for(int i=a;i<=b;i++)#define N 50005#define M 2500#define S 50using namespace std;const int mo=536870912;struct note{int v,w;}a[N],b[N];bool cmp(note x,note y) {return x.v<y.v;}int L[M],R[M],Len[M],l[M][S],r[M][S],sz[M],len[M][S],pos[N],n,m,q,op,x,y,u,v;int Sum[M],Mul[M],Add[M],sum[M][S],mul[M][S],add[M][S],p[N],ans,Mult,Plus;int get() { char ch;while (!isdigit(ch=getchar())); int o=ch-48;while (isdigit(ch=getchar())) o=o*10+ch-48; return o;}void make(int x) { sz[x]=Len[x]/S+((Len[x]%S)>0); fo(i,1,sz[x]) { l[x][i]=max(r[x][i-1]+1,L[x]); r[x][i]=min(l[x][i]+S,R[x]); len[x][i]=r[x][i]-l[x][i]+1; mul[x][i]=1; }}void Down(int x) { (Sum[x]*=Mul[x])+=Len[x]*Add[x]; fo(i,1,sz[x]) mul[x][i]*=Mul[x],(add[x][i]*=Mul[x])+=Add[x]; Mul[x]=1;Add[x]=0;}void down(int x,int y) { (sum[x][y]*=mul[x][y])+=len[x][y]*add[x][y]; fo(i,l[x][y],r[x][y]) (p[i]*=mul[x][y])+=add[x][y]; mul[x][y]=1;add[x][y]=0;}void Updata(int x) { Sum[x]=0; fo(i,1,sz[x]) Sum[x]+=sum[x][i]*mul[x][i]+len[x][i]*add[x][i];}void updata(int x,int y) { sum[x][y]=0; fo(i,l[x][y],r[x][y]) sum[x][y]+=p[i];}void change(int v,int x,int y) { fo(i,1,sz[v]) if (x<=b[l[v][i]].v&&b[r[v][i]].v<=y) mul[v][i]*=Mult,(add[v][i]*=Mult)+=Plus; else if (max(x,b[l[v][i]].v)<=min(y,b[r[v][i]].v)) { down(v,i); fo(j,l[v][i],r[v][i]) if (x<=b[j].v&b[j].v<=y) (p[j]*=Mult)+=Plus; updata(v,i); } Updata(v);}int query(int v,int x,int y) { int ans=0; fo(i,1,sz[v]) if (x<=b[l[v][i]].v&&b[r[v][i]].v<=y) ans+=sum[v][i]*mul[v][i]+len[v][i]*add[v][i]; else if (max(x,b[l[v][i]].v)<=min(y,b[r[v][i]].v)){ down(v,i); fo(j,l[v][i],r[v][i]) if (x<=b[j].v&&b[j].v<=y) ans+=p[j]; } return ans;}int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); n=get();q=get(); fo(i,1,n) b[i].v=get(),b[i].w=i; m=n/M+((n%M)>0); fo(i,1,m) { L[i]=R[i-1]+1;R[i]=min(L[i]+M,n);Len[i]=R[i]-L[i]+1; sort(b+L[i],b+R[i]+1,cmp);make(i);Mul[i]=1; fo(j,L[i],R[i]) pos[j]=i; } fo(i,1,n) a[b[i].w].w=i; for(;q;q--) { op=get();x=get();y=get();ans=0; if (op<=1) Mult=get(),Plus=get(); if (!op) { u=pos[x];v=pos[y]; if (u==v) { Down(u);fo(i,1,sz[u]) down(u,i); fo(i,x,y) (p[a[i].w]*=Mult)+=Plus; fo(i,1,sz[u]) updata(u,i);Updata(u); continue; } Down(u);fo(i,1,sz[u]) down(u,i); fo(i,x,R[u]) (p[a[i].w]*=Mult)+=Plus; fo(i,1,sz[u]) updata(u,i);Updata(u); Down(v);fo(i,1,sz[v]) down(v,i); fo(i,L[v],y) (p[a[i].w]*=Mult)+=Plus; fo(i,1,sz[v]) updata(v,i);Updata(v); fo(i,u+1,v-1) Mul[i]*=Mult,(Add[i]*=Mult)+=Plus; } else if (op==1) fo(i,1,m) Down(i),change(i,x,y); else if (op==2) { u=pos[x];v=pos[y]; if (u==v) { Down(u);fo(i,1,sz[u]) down(u,i); fo(i,x,y) ans+=p[a[i].w]; printf("%d\n",(ans%mo+mo)%mo); continue; } Down(u);fo(i,1,sz[u]) down(u,i); fo(i,x,R[u]) ans+=p[a[i].w]; Down(v);fo(i,1,sz[v]) down(v,i); fo(i,L[v],y) ans+=p[a[i].w]; fo(i,u+1,v-1) ans+=Sum[i]*Mul[i]+Len[i]*Add[i]; } else fo(i,1,m) Down(i),ans+=query(i,x,y); if (op>=2) printf("%d\n",(ans%mo+mo)%mo); }}
Ps:这是一个超时代码,其余优化留给读者自行思考。
0 0
- 【NOIP2013模拟联考7】数列
- 【NOIP2013模拟联考7】OSU
- 【NOIP2013模拟联考13】线段
- 【NOIP2013模拟联考5】军训
- 【NOIP2013模拟联考6】选课
- 【NOIP2013模拟联考7】最长上升子序列
- JZOJ 3468. 【NOIP2013模拟联考7】OSU!(osu)
- 3467. 【NOIP2013模拟联考7】最长上升子序列(lis)
- 【NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考6】选课(select)
- 【NOIP2013模拟联考5】军训(training) 题解
- NOIP2013模拟联考5】军训(training)
- 【NOIP2013模拟联考2】摘取作物(pick)
- 【NOIP2013模拟联考3】山峰(summits)
- 【NOIP2013模拟联考15】人类基因组(genes)
- 【NOIP2013模拟联考10】独立集(bubble)
- JZOJsenior3484.【NOIP2013模拟联考10】密码(substring)
- 【NOIP2013模拟联考14】图形变换(transform)
- struts接受前端传来的参数的时候,无法调式set方法(看不到变量的值)
- Valid Parentheses 合法括号
- mybaits的Mapper动态代理的简单例子(定义类型别名,ResultMap类型的使用)
- <input type='file'> accept属性
- Link-Cut Tree
- 【NOIP2013模拟联考7】数列
- 正则表达式--------grep
- python websocket.WebSocketApp笔记
- 查看OpenGL版本
- 22. Generate Parentheses
- 【BZOJ2751】【codevs1853】容易题,快速幂+逆元
- 初学CentOS——常见小命令
- 阿里音乐预测 之 初探ODPS SQL
- linux 挂死问题定位分析