1741:电子速度
时间限制: 4000 ms 内存限制: 524288 KB
【题目描述】
选取显像管的任意一个平面,一开始平面内有n个电子,初始速度分别为vi ,定义飘升系数为:
电子的速度常常会发生变化。也就是说,有两种类型的操作:
•1pxy将 改为 (x,y);
•2lr询问[l,r]这段区间内的电子的飘升系数。
答案对20170927取模即可。
【输入】
第一行两个整数n,m,表示电子个数和询次个数。
接下来n行, 每行两个整数 x,y表示 vi。
接下来m行, 每行形如1 p x y或 2 l r,分别表示两种操作。
【输出】
对于每个操作2,输出一行一个整数表示飘升系数对 20170927 取模的值。
【输入样例】
9 5 13052925 5757314 9968857 11135327 13860145 3869873 6912189 3461377 2911603 7061332 6334922 7708411 5505379 5915686 6806727 588727 7603043 15687404 2 1 6 1 7 2602783 18398476 1 8 8636316 19923037 2 2 7 2 2 4
【输出样例】
18529202 963126 19167545
【提示】
【数据规模与约定】
测试点编号 | n | m |
1 | ≤100 | ≤100 |
2 | ≤500 | ≤500 |
3 | ≤1000 | ≤1000 |
4 | ≤5000 | ≤5000 |
5 | ≤10000 | ≤10000 |
6 | ≤50000 | ≤50000 |
7 | ≤100000 | ≤100000 |
8 | ≤500000 | ≤500000 |
9 | ≤1000000 | ≤1000000 |
10 | ≤1000000 | ≤1000000 |
对于100%的数据,1≤n,m≤10^6,0≤xi,yi<20170927,1≤li≤ri≤n。
然后就可以构造三个树状数组去记录着三个值即可
代码
#include<bits/stdc++.h>
#pragma GCC optimize(3)
using namespace std;
const int maxn=1e6+5;
const int mod=20170927;
int x[maxn],y[maxn],n,m;
long long a[maxn],b[maxn],c[maxn];
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int lb(int x)
{
return x&-x;
}
void add(int pos,long long x,long long y)
{
for(;pos<=n;pos+=lb(pos))
{
a[pos]=(a[pos]+(x*x)%mod+mod)%mod;
b[pos]=(b[pos]+(y*y)%mod+mod)%mod;
c[pos]=(c[pos]+(x*y)%mod+mod)%mod;
}
}
void del(int pos,long long x,long long y)
{
for(;pos<=n;pos+=lb(pos))
{
a[pos]=(a[pos]-(x*x)%mod+mod)%mod;
b[pos]=(b[pos]-(y*y)%mod+mod)%mod;
c[pos]=(c[pos]-(x*y)%mod+mod)%mod;
}
}
long long calca(int pos)
{
long long res=0;
for(;pos;pos-=lb(pos)) res=(res+a[pos])%mod;
return res;
}
long long calcb(int pos)
{
long long res=0;
for(;pos;pos-=lb(pos)) res=(res+b[pos])%mod;
return res;
}
long long calcc(int pos)
{
long long res=0;
for(;pos;pos-=lb(pos)) res=(res+c[pos])%mod;
return res;
}
long long querya(int l,int r)
{
return (calca(r)-calca(l-1)+mod)%mod;
}
long long queryb(int l,int r)
{
return (calcb(r)-calcb(l-1)+mod)%mod;
}
long long queryc(int l,int r)
{
return (calcc(r)-calcc(l-1)+mod)%mod;
}
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
x[i]=read(); y[i]=read();
add(i,x[i],y[i]);
}
int aa,bb,cc;
for(int i=1;i<=m;i++)
{
int op=read();
if(op==1)
{
aa=read(); bb=read(); cc=read();
del(aa,x[aa],y[aa]);
add(aa,bb,cc);
x[aa]=bb; y[aa]=cc;
}
if(op==2)
{
aa=read(); bb=read();
long long res=querya(aa,bb)*queryb(aa,bb)%mod;
long long ress=queryc(aa,bb);
res=(res-ress*ress%mod+mod)%mod;
printf("%lld\n",res);
}
}
return 0;
}