洛谷八连测——关于取模与思维僵化

来源:互联网 发布:马天宇是不是同志知乎 编辑:程序博客网 时间:2024/06/08 08:33

有一天小妖精们又在做游戏。这个游戏是这样的。

妖精仓库的储物点可以看做在一个数轴上。每一个储物点会有一些东西,同时他们之间存在距离。

每次他们会选出一个小妖精,然后剩下的人找到区间[l,r][l,r]储物点的所有东西,清点完毕之后问她,把这个区间内所有储物点的东西运到另外一个仓库的代价是多少?

比如储物点ii有xx个东西,要运到储物点jj,代价为

x * dis( i , j )

dist就是仓库间的距离。

当然啦,由于小妖精们不会算很大的数字,因此您的答案需要对19260817取模。

输入输出格式

输入格式:
第一行两个数表示n,mn,m
第二行n-1n−1个数,第ii个数表示第ii个储物点与第i+1i+1个储物点的距离

第三行nn个数,表示每个储物点的东西个数

之后mm行每行三个数x l r

表示查询要把区间[l,r][l,r]储物点的物品全部运到储物点x的花费

输出格式:
对于每个询问输出一个数表示答案

输入输出样例

输入样例#1:
5 5
2 3 4 5
1 2 3 4 5
1 1 5
3 1 5
2 3 3
3 3 3
1 5 5
输出样例#1:
125
72
9
0
70
说明

对于30%的数据,n , m \le 1000n,m≤1000
对于另外20%的数据,所有储物点间的距离都为1

对于另外20%的数据,所有储物点的物品数都为1

对于100%的数据 , n , m <= 200000 ;n,m≤200000;ai,bi<=2⋅10^9


洛谷月赛题

具体解法见题解这里记录一些错误与注意事项

1 思维僵化

bzoi LittlePrincess十分喜爱安利树状数组,众所周知。
然后这道题的数据范围是20w 很自然想到nlogn复杂度哇,加之本蒟蒻喜爱安利树状数组,然后就写了个树状数组。。写完发现不用动态QAQ。。

①静态题不要想bit数组!
②不要被数据范围蒙蔽!

2 模法

/*     (a + b) mod n = ((a mod n) + (b mod n)) mod n     (a - b) mod n = ((a mod n) - (b mod n) + n) mod n     (a * b) mod n = ((a mod n) * (b mod n)) mod n     对于除法没有类似公式,但是可以通过求逆元的方法,转换成乘法运算求模(见下面) */  

取膜一定要按照法则,不要yy,更不要xjb模
下面是很沙茶的bit数组代码

#include<bits/stdc++.h>using namespace std;#define lb(x) x&-x#define LL long long#define MN 200010int n,m,ll,rr,dis[MN],dep[MN],c1[MN],c2[MN],a[MN],x,p=19260817;void ad2(int x,int pos){    for(;pos<=n;pos+=lb(pos)) c2[pos]+=x,c2[pos]%=p;}void ad1(int x,int pos){    for(;pos<=n;pos+=lb(pos)) c1[pos]+=x,c1[pos]%=p;}int gsum1(int pos){    int ans=0;    for(;pos;pos-=lb(pos)) {ans+=c1[pos],ans%=p;}    return ans;}int gsum2(int pos){    int ans=0;    for(;pos;pos-=lb(pos)) {ans+=c2[pos],ans%=p;}    return ans;}int work(int l,int r,int k,int x){    if(l>r) return 0;int ans=0;    int wor=(((gsum2(r)-gsum2(l-1))%p+p)%p);    int rwz=((gsum1(r)-gsum1(l-1))%p+p)%p;    int xgz=((dis[x]%p)*(((gsum2(r)-gsum2(l-1))%p+p)%p))%p;    if(k==-1)     ans=((rwz-xgz)%p);    else ans=((xgz-rwz+p)%p)%p;    return ans;}int main(){    //freopen("sample4.in","r",stdin);    //freopen("a.txt","w",stdout);    cin>>n>>m;    for(int i=2,_;i<=n;i++)    {cin>>_;dis[i]=(dis[i-1]+_)%p;}    for(int i=1;i<=n;i++){cin>>a[i];a[i]%=p;ad2(a[i],i);}    for(int i=1;i<=n;i++)     dep[i]=(((dis[i]%p)*(a[i]%p))%p+p)%p,ad1(dep[i],i);    while(m--)    {        cin>>x>>ll>>rr;        if(x>rr) cout<<work(ll,rr,1,x)<<endl;        else if(x<ll) cout<<work(ll,rr,-1,x)<<endl;        else cout<<(work(ll,x-1,1,x)+work(x+1,rr,-1,x))%p<<endl;    }}

下面是ac代码

#include<bits/stdc++.h>using namespace std;#define LL long long#define MN 200010int n,m,ll,rr,dis[MN],sum1[MN],sum2[MN],a[MN],x,p=19260817;int work(int l,int r,int k,int x){    if(l>r) return 0;    return     k==-1?((sum1[r]-sum1[l-1]+p)%p-((LL)dis[x]*((sum2[r]-sum2[l-1]+p)%p))%p+p)%p    :(((LL)dis[x]*((sum2[r]-sum2[l-1]+p)%p))%p-(sum1[r]-sum1[l-1]+p)%p+p)%p;}int main(){//  freopen("sample3.in","r",stdin);//  freopen("a.txt","w",stdout);    cin>>n>>m;for(int i=2,_;i<=n;i++)     cin>>_,dis[i]=(dis[i-1]+_)%p;//sum1[i]=(sum1[i-1]+dis[i])%p;    for(int i=1;i<=n;i++)     cin>>a[i],a[i]%=p,sum2[i]=(sum2[i-1]+a[i])%p,sum1[i]=(sum1[i-1]+((LL)a[i]*dis[i])%p)%p;//  for(int i=1;i<=n;i++) if(sum2[i]<0||dis[i]<0||a[i]<0) cout<<" swdwd";    while(m--)    {        cin>>x>>ll>>rr;        if(x>rr) cout<<work(ll,rr,1,x)<<endl;        else if(x<ll) cout<<work(ll,rr,-1,x)<<endl;        else cout<<(work(ll,x-1,1,x)+work(x+1,rr,-1,x))%p<<endl;    }     return 0;}
原创粉丝点击