2015上海网络赛 HDU 5475 An easy problem 线段树

题意就不说了

思路:线段树,维护区间乘积。2操作就将要除的点更新为1.

 

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<queue>
  7 #include<vector>
  8 #include<set>
  9 #include<string>
 10 #define inf 0x3f3f3f3f
 11 #define LL long long
 12 #define mid(a,b) ((a+b)>>1)
 13 #define ll long long
 14 #define maxn 110000
 15 #define IN freopen("in.txt","r",stdin);
 16 using namespace std;
 17 
 18 LL mod;
 19 LL num[maxn];
 20 struct Tree
 21 {
 22     int left,right;
 23     LL pro;    /*pro为区间和,可改为最大值最小值等*/
 24 }tree[maxn<<2]; /*四倍大小*/
 25 
 26 
 27 /*递归建树*/
 28 void build(int i,int left,int right)
 29 {
 30     tree[i].left=left;
 31     tree[i].right=right;
 32 
 33     if(left==right){
 34         tree[i].pro=num[left]%mod;
 35         return ;
 36     }
 37 
 38     int mid=mid(left,right);
 39 
 40     build(i<<1,left,mid);
 41     build(i<<1|1,mid+1,right);
 42 
 43     tree[i].pro=(tree[i<<1].pro*tree[i<<1|1].pro)%mod;
 44 }
 45 
 46 /*单点修改,d为改变量,两函数可共存*/
 47 void update(int i,int x,LL d)
 48 {
 49     if(tree[i].left==tree[i].right){
 50         tree[i].pro=d;
 51         return;
 52     }
 53 
 54     int mid=mid(tree[i].left,tree[i].right);
 55 
 56     if(x<=mid) update(i<<1,x,d);
 57     else update(i<<1|1,x,d);
 58 
 59     tree[i].pro=(tree[i<<1].pro*tree[i<<1|1].pro)%mod;
 60 }
 61 
 62 /*区间结果查询*/
 63 LL query(int i,int left,int right)
 64 {
 65     if(tree[i].left==left&&tree[i].right==right)
 66         return tree[i].pro%mod;
 67 
 68     int mid=mid(tree[i].left,tree[i].right);
 69 
 70     if(right<=mid) return query(i<<1,left,right);
 71     else if(left>mid) return query(i<<1|1,left,right);
 72     else return (query(i<<1,left,mid)*query(i<<1|1,mid+1,right))%mod;
 73 }
 74 
 75 int main(int argc, char const *argv[])
 76 {
 77     //IN;
 78 
 79     int t,ca=1;scanf("%d",&t);
 80     while(t--)
 81     {
 82         printf("Case #%d:\n",ca++);
 83         int n;scanf("%d %lld",&n,&mod);
 84         //fill(num,num+maxn,1);
 85         int type[maxn];LL val[maxn];
 86         for(int i=1;i<=n;i++){
 87             scanf("%d %lld",&type[i],&val[i]);
 88             if(type[i]==1) num[i]=val[i];
 89             if(type[i]==2) num[i]=1;
 90         }
 91         build(1,1,n);
 92         for(int i=1;i<=n;i++){
 93             if(type[i]==1){
 94                 LL ans=query(1,1,i);
 95                 printf("%lld\n",ans%mod);
 96             }
 97             else if(type[i]==2){
 98                 update(1,val[i],1LL);
 99                 LL ans=query(1,1,i);
100                 printf("%lld\n",ans%mod);
101             }
102         }
103 
104     }
105 
106     return 0;
107 }

 

你可能感兴趣的:(2015上海网络赛 HDU 5475 An easy problem 线段树)