Problem Description
To be a friend of this gay, you have been invented by him to play this interesting game with him. Of course, you need to work out the answers faster than him to get a free lunch, He he…
Input
For each test case, the first line is the length of sequence n (n<=50000), the second line has n numbers, they are the initial n numbers of the sequence a1,a2, …,an,
Then the third line is the number of operation q (q<=50000), from the fourth line to the q+3 line are the description of the q operations. They are the one of the two forms:
0 k1 k2; you need to work out the multiplication of the subsequence from k1 to k2, inclusive. (1<=k1<=k2<=n)
1 k p; the kth number of the sequence has been change to p. (1<=k<=n)
You can assume that all the numbers before and after the replacement are no larger than 1 million.
Output
Sample Input
1 6 1 2 4 5 6 3 3 0 2 5 1 3 7 0 2 5
Sample Output
240
420
這個題,一道線段樹的題,題目的意思容易理解。就是
先輸入一個序列,然後 後面m個數據。 第一個爲0的話,就
輸出第k1 到k2的之間的積,如果是0的話,就把第k 的值改成p
注意積的值對100000007取模, long long 下 lld輸出即可
無語的wa點在定義樹的結構體的時候,沒把節點的值long long
找錯 那個心累
#include<iostream>
#include<cstring>
using namespace std;
const int mod=1000000007;
struct node
{
int left,right;
long long num;
}s[150005];
int a[50010];
void build(int ll,int rr,int i) //建線段樹
{
int mm;
s[i].left=ll; s[i].right=rr; //左右區間給樹的數組
if(ll==rr) //達到葉結點
{
s[i].num=a[ll]; //先用數組存下該隊的人
return ;
}
mm=(ll+rr)/2; //二分思想
build(ll,mm,2*i); //左子樹
build(mm+1,rr,2*i+1); //右子樹
s[i].num=(s[2*i].num*s[2*i+1].num)%mod;
}
void updata(int y,int x,int i) //值 位置
{
if(s[i].left==x&&x==s[i].right)
{
s[i].num=y;
return; //到達葉子節點
}
if(x<=s[2*i].right) updata(y,x,2*i);
if(x>=s[2*i+1].left) updata(y,x,2*i+1);
s[i].num=(s[2*i].num*s[2*i+1].num)%mod;
}
long long sum(int ll,int rr,int i) //查詢
{
int mm;
if(s[i].left==ll&&rr==s[i].right) //如果區間覆蓋,則直接返回其節點的值
{
return s[i].num;
}
mm=(s[i].left+s[i].right)/2;
if(rr<=mm) return sum(ll,rr,2*i); //左子樹
if(ll>mm) return sum(ll,rr,2*i+1); //右子樹
else
{
long long a=sum(ll,mm,2*i);
long long b=sum(mm+1,rr,2*i+1);
return (a*b)%mod; //左右之間
}
}
int main()
{
int bbs,k,i,j,n,m,x,y;
scanf("%d",&bbs);
while(bbs--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1); //建樹
scanf("%d",&m);
while(m--)
{
scanf("%d%d%d",&k,&x,&y);
if(k==0)
{
long long ans=sum(x,y,1);
ans=ans%mod;
printf("%lld\n",ans);
}
else updata(y,x,1); //值 和 位置
}
}
return 0;
}